2 3 3 1 2 2 3 3 1 7 6 1 2 1 3 1 4 1 5 1 6 1 7
1 1 1 0 1 0 1 0 1
题:给出n个点,m条无向边,现在要求将无向边变为有向边,要保证每个点的出度和入度的差不超过1
思路来自:http://blog.csdn.net/winddreams/article/details/47281397
直接进行搜索,对每个点进行出度和入度的判断,如果出度大,就先进行反向的搜索(每搜索一条边u,v就认为这是一条v到u的有向边),反之,进行正向搜索(每搜到一条边u,v认为这是一条u到v的有向边),一直搜索到找不到边能继续为止。
对于已经判断过的边删去:head[u] = edge[i].next;
证明不会有-1的情况,对于一个点v,假设入度比出度多2,那么,第一:就会有一条边搜索到v后找不到后继,导致v的入度比出度多1,第二:又有一条边搜索到v,导致v的入度比出度多2,但是这样的话就会和第一条找不到后继冲突,所以不会出现入度比出度多2的情况,(其他情况也是类似),所以不会有-1的结果。
(果然稍难一点自己就不知道怎么办了 好坑orz)
#include <iostream> #include <cstdio> #include<algorithm> #include<cstring> #include<functional> #include<queue> typedef long long ll; using namespace std; struct node { int u,v,ci; int next; } edge[700000]; int n,m,to; int head[100010] , vis[700000] ; int in[100010] , out[100010] , num[100010] ; int ans[700000] ; void add(int u,int v,int c) { edge[to].u= u; edge[to].v= v; edge[to].ci = c; edge[to].next = head[u]; head[u] = to++; } void dfs1(int u) //正向搜索 { for(int i = head[u]; ~i; i = edge[i].next) { if(vis[i]) { head[u] = edge[i].next; //删边 continue; } int v = edge[i].v; if(u != v && in[v] > out[v]) //u->v,in[v] > out[v]时,跳过 continue; vis[i] = vis[i^1] = 1; //将u,v之间的两条边标记 if(i %2) //有输入可知,i为偶时u->v; i为奇时,v->u ans[i/2] = 0; else ans[i/2] = 1; out[u]++; in[v]++; head[u] = edge[i].next; dfs1(v); break; } } void dfs2(int u) { for(int i = head[u]; ~i; i = edge[i].next) { if(vis[i]) { head[u] = edge[i].next; continue; } int v = edge[i].v; if(u != v && in[v] < out[v]) continue; vis[i] = vis[i^1] = 1; if(i %2) ans[i/2] = 1; else ans[i/2] = 0; out[v]++; in[u]++; head[u] = edge[i].next; dfs2(v); break; } } int main() { int T; int a, b; scanf("%d",&T); while(T--) { to = 0; scanf("%d%d",&n,&m); memset(vis,0,sizeof(vis)); for(int i = 0;i <= n;i++) { in[i] = out[i] = num[i] = 0;head[i] = -1; } for(int i = 0; i < m; i++) { scanf("%d%d",&a,&b); add(a,b,i); add(b,a,i); num[a]++; num[b]++; } for(int i = 1; i <= n; i++) { while(in[i] + out[i] < num[i]) { if(in[i] >= out[i]) //正反不停搜,直到找不到边为止 dfs1(i); else dfs2(i); } } for(int i = 0; i < m; i++) printf("%d\n",ans[i]); } return 0; }