洛谷UVA10054 The Necklace
大玄学事件
欧拉回路:并查集判断是否连通(也可以dfs)输出边要在dfs后面一排(why,玄学)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e4+5;
int head[maxn],nex[maxn],to[maxn],tot = 1,vis[maxn],num[maxn],father[maxn];
int d, f,a[maxn],b[maxn],in[maxn],dp[maxn];
int n,m,s,t;
void add(int x,int y){
to[++tot] = y;nex[tot] = head[x];head[x] = tot;
}
int Find(int x){
if(father[x]==x)return x;
int r=x;
while(father[x]!=r){
r=father[x];
father[x]=father[r];}
return father[x];
}
void Union(int x,int y){
x=Find(x);
y=Find(y);
if(x!=y)
father[x]=y;
}
void dfs(int x){
for(int i=head[x];i;i=nex[i]){
if(vis[i])continue;//遍历过的边不再遍历
int y=to[i];
vis[i]=1;
vis[i^1]=1;
dfs(y);
printf("%d %d\n",y,x);//玄学,感觉写在dfs的上一排一个也可以
}
}
int main(){
scanf("%d",&t);
for(int r=1;r<=t;r++){
f=1;
memset(father,0,sizeof(father));
memset(in,0,sizeof(in));
memset(dp,0,sizeof(dp));
memset(vis,0,sizeof(vis));
memset(head,0,sizeof(head));
memset(num,0,sizeof(num));
tot=1;
scanf("%d",&n);
for(int i=1;i<=n;i++){
int x,y;
scanf("%d%d",&a[i],&b[i]);
num[a[i]]=1,num[b[i]]=1;
father[a[i]]=a[i],father[b[i]]=b[i];
in[a[i]]++,in[b[i]]++;
add(a[i],b[i]);add(b[i] ,a[i]);
}
for(int i=1;i<=50;i++){
if(num[i]){
if(in[i]&1){
f=0;
break;
}
}
}
for(int i=1;i<=n;i++){
Union(a[i],b[i]);
}
int ssc=0;
for(int i=1;i<=50;i++)
if(num[i]&&father[i]==i)
ssc++;
if(ssc>1)f=0;
if(f==0)printf("Case #%d\nsome beads may be lost\n",r);
else{
printf("Case #%d\n",r);
dfs(a[1]);
}
printf("\n");
}
}