对每个点DFS,根据入度和出度的情况选择标记入边或者出边进行DFS
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
/* *********************************************** Author :CKboss Created Time :2015年08月05日 星期三 10时51分53秒 File Name :HDOJ5348.cpp ************************************************ */ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <string> #include <cmath> #include <cstdlib> #include <vector> #include <queue> #include <set> #include <map> #pragma comment(linker, "/STACK:102400000,102400000") using namespace std; const int maxn=100100; int n,m; struct Edge { int to,next; }edge[maxn*6]; int Adj[maxn],Size; void init() { memset(Adj,-1,sizeof(Adj)); Size=0; } void Add_Edge(int u,int v) { edge[Size].to=v; edge[Size].next=Adj[u]; Adj[u]=Size++; } bool vis[maxn*6]; int ans[maxn*3],in[maxn],out[maxn],num[maxn]; void clear() { init(); memset(ans,0,sizeof(ans)); memset(vis,0,sizeof(vis)); memset(num,0,sizeof(num)); memset(in,0,sizeof(in)); memset(out,0,sizeof(out)); } /// u--->v void dfs0(int u) { for(int i=Adj[u];~i;i=edge[i].next) { if(vis[i]==true) { Adj[u]=edge[i].next; continue; } int v=edge[i].to; if(v!=u&&in[v]>out[v]) continue; vis[i]=vis[i^1]=true; if(i%2==0) ans[i/2]=0; else ans[i/2]=1; out[u]++; in[v]++; Adj[u]=edge[i].next; dfs0(v); return ; } } /// u<----v void dfs1(int u) { for(int i=Adj[u];~i;i=edge[i].next) { if(vis[i]==true) { Adj[u]=edge[i].next; continue; } int v=edge[i].to; if(v!=u&&in[v]<out[v]) continue; vis[i]=vis[i^1]=true; if(i%2==0) ans[i/2]=1; else ans[i/2]=0; out[v]++; in[u]++; Adj[u]=edge[i].next; dfs1(v); return ; } } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int T_T; scanf("%d",&T_T); while(T_T--) { clear(); scanf("%d%d",&n,&m); for(int i=0,u,v;i<m;i++) { scanf("%d%d",&u,&v); /// edgeid Size/2; Add_Edge(u,v); /// Size%2==0 real edge Add_Edge(v,u); num[u]++; num[v]++; } for(int i=1;i<=n;i++) { while(in[i]+out[i]!=num[i]) { if(in[i]>=out[i]) dfs0(i); else dfs1(i); } } for(int i=0;i<m;i++) printf("%d\n",ans[i]); } return 0; }