HDU5348
解读题意
1.给每条边定向,令每个点|出度-入度|<=1
分析策略
1.如果这个点属于欧拉回路那么一定满足条件
2.如果这个点属于欧拉路径那么也满足条件
3.如果把这幅图按一定方式补成欧拉回路那么一定满足条件
4.如果都是偶数点,直接满足条件
5.否则,把奇数点两两相连(每个奇数点只连一条边,奇数点一个是偶数个)
具体代码
#include<bits/stdc++.h>
using namespace std;
const int M=100005;
int n,m;
int asdf,head[M];
int ans[M*4],du[M],q[M];
bool mark[M*4];
struct edge {
int to,nxt,id,f;
} G[M*7];
void add_edge(int a,int b,int c,int d) {
G[++asdf].to=b;
G[asdf].nxt=head[a];
G[asdf].id=c;
G[asdf].f=d;
head[a]=asdf;
mark[c]=0;
}
void dfs(int x) {
for(int &i=head[x]; i; i=G[i].nxt) {
if(mark[G[i].id])continue;
int y=G[i].to,c=G[i].id;
mark[G[i].id]=1;
ans[G[i].id]=G[i].f;
dfs(y);
}
}
int main() {
int cas;
int a,b;
scanf("%d",&cas);
while(cas--) {
scanf("%d %d",&n,&m);
asdf=0;
for(int i=1; i<=n; i++)head[i]=du[i]=0;
for(int i=1; i<=m; i++) {
scanf("%d %d",&a,&b);
add_edge(a,b,i,1);
add_edge(b,a,i,0);
du[a]++,du[b]++;
ans[i]=-1;
}
int len=0;
for(int i=1; i<=n; i++) {
if(du[i]&1) {
q[++len]=i;
}
}
for(int i=2; i<=len; i+=2) {
add_edge(q[i-1],q[i],m+i/2,1);
add_edge(q[i],q[i-1],m+i/2,0);
}
for(int i=1; i<=n; i++) {
if(head[i]) {
dfs(i);
}
}
for(int i=1; i<=m; i++)printf("%d\n",ans[i]);
}
return 0;
}