题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5348
题意:给你一个无向图,要你将无向图的边变成有向边,使得得到的图,出度和入度差的绝对值小于等于1,如果无解输出-1
解:考虑奇数度的点一定会成对出现(因为所有度数和肯定是偶数个->一条边对应两度~),那么我们可以将奇数度的点两两一连消除掉(两奇数度点的出度入读差的绝对值都为1, 路径上的点的差绝对值为0)
然后偶数度的点可以成环,那么可以搜出所有的环
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 2 * Problem: 3 * Author: SHJWUDP 4 * Created Time: 2015/8/5 星期三 16:29:03 5 * File Name: 1006.cpp 6 * State: 7 * Memo: 8 */ 9 #include <iostream> 10 #include <cstdio> 11 #include <vector> 12 #include <cstring> 13 #include <algorithm> 14 15 using namespace std; 16 17 struct Edge { 18 int u, v; 19 }; 20 21 int n, m; 22 vector<Edge> edges; 23 vector<vector<int> > G; 24 vector<int> cur, dg, vis, ans; 25 void init(int N, int M) { 26 edges.clear(); 27 G.assign(N, vector<int>(0)); 28 cur.assign(N, 0); 29 vis.assign(M<<1, 0); 30 ans.assign(M, -1); 31 dg.assign(N, 0); 32 } 33 void addEdge(int u, int v) { 34 edges.push_back((Edge){u, v}); 35 G[u].push_back(edges.size()-1); 36 } 37 void euler(int u) { 38 while(cur[u]<(int)G[u].size()) { 39 int i=G[u][cur[u]]; 40 if(vis[i]) { 41 cur[u]++; continue; 42 } 43 Edge & e=edges[i]; 44 if(i & 1) ans[i>>1]=0; 45 else ans[i>>1]=1; 46 vis[i]=vis[i^1]=1; 47 cur[u]++; 48 dg[e.u]--; dg[e.v]--; 49 u=e.v; 50 } 51 } 52 int main() { 53 #ifndef ONLINE_JUDGE 54 freopen("in", "r", stdin); 55 //freopen("out", "w", stdout); 56 #endif 57 int T; 58 scanf("%d", &T); 59 while(T--) { 60 scanf("%d%d", &n, &m); 61 init(n+1, m+1); 62 for(int i=0; i<m; i++) { 63 int a, b; 64 scanf("%d%d", &a, &b); 65 addEdge(a, b); 66 addEdge(b, a); 67 dg[a]++; dg[b]++; 68 } 69 for(int i=1; i<=n; i++) { 70 if(dg[i] & 1) euler(i); 71 } 72 for(int i=1; i<=n; i++) { 73 if(dg[i] > 0) euler(i); 74 } 75 for(int i=0; i<m; i++) { 76 printf("%d ", ans[i]); 77 } 78 } 79 return 0; 80 }