2 3 3 1 2 2 3 3 1 7 6 1 2 1 3 1 4 1 5 1 6 1 7
题目:把无向边变有向边,每个点的出度入度只差小于等于1
:把环找出来,一个环上,每个点的入度=出度
:剩下一片森林,森林里dfs保证每个结点的出度与入度只差相差1即可。一定有答案
http://blog.sina.com.cn/s/blog_15139f1a10102vokk.html 解题报告
#pragma comment(linker, "/STACK:102400000,102400000") #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> using namespace std; struct Node{ int u,v,id,f; }; #define maxn 100007 vector<Node>head[maxn]; vector<Node>edge; int in[maxn],out[maxn],check[maxn*5],result[maxn*5]; int cnt = 0; vector<Node>stack; int dfn[maxn]; int olar(int u,int dep){ Node p,q; dfn[u] = dep; while(head[u].size() > 0){ p = head[u][head[u].size()-1]; head[u].pop_back(); if(check[p.id]) continue; check[p.id] = 1; stack.push_back(p); if(dfn[p.v] != -1 ) { dfn[u] = -1; return p.v; } int v = olar(p.v,dep+1); if( v != 0){ if( v == u){ for(int i = dep;i < stack.size(); i++){ q = stack[i]; result[q.id] = q.f; } while(stack.size() > dep) stack.pop_back(); } else { dfn[u] = -1; return v; } } else stack.pop_back(); } dfn[u] = -1; return 0; } void dfs(int u){ int v; Node p; while(head[u].size() > 0){ p = head[u][head[u].size()-1]; head[u].pop_back(); if(check[p.id]) continue; check[p.id] = 1; if(out[u] > in[u]){ in[u]++; out[p.v]++; result[p.id] = p.f; } else { out[u]++; in[p.v]++; result[p.id] = !p.f; } dfs(p.v); } } int main(){ int t,n,m; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); for(int i = 1;i <= n; i++) in[i] = out[i] = 0, dfn[i] = -1; for(int i = 0;i < m; i++) check[i] = 0,result[i] = -1; Node p; edge.clear(); for(int i = 1;i <= n; i++) head[i].clear(); for(int i = 0;i < m; i++){ scanf("%d%d",&p.u,&p.v); p.f = 1; p.id = i; edge.push_back(p); if(p.u == p.v){ result[p.id] = 1; continue; } head[p.u].push_back(p); swap(p.u,p.v); p.f = 0; head[p.u].push_back(p); } for(int i = 1;i <= n; i++) if(head[i].size() > 0) olar(i,0); //cout<<"x"<<endl; for(int i = 0;i < m; i++){ if(result[i] == -1){ p = edge[i]; head[p.u].push_back(p); swap(p.u,p.v); p.f = 0; head[p.u].push_back(p); } check[i] = 0; } for(int i = 1;i <= n; i++) if(head[i].size() > 0) { dfs(i); } int ans = 1; //cout<<cnt<<endl; for(int i = 1;i <= n; i++) if(in[i] > out[i] +1 || in[i] + 1 < out[i]) ans = -1; if(ans == -1){ printf("-1\n"); } else for(int i = 0;i < m; i++) printf("%d\n",result[i]); } return 0; } /* 55 4 20 1 1 2 2 3 3 4 4 1 2 1 2 1 2 1 2 2 3 2 3 2 3 2 3 3 4 3 4 3 4 3 4 4 1 4 1 4 1 4 1 3 3 1 2 2 3 3 1 7 6 1 2 1 3 1 4 1 5 1 6 1 7 */