Uva10054 无向图打印任意欧拉回路

来源:互联网 发布:淘宝上hm折扣代购真假 编辑:程序博客网 时间:2024/05/18 20:31

题意 有一些双色水珠,串成一条项链,前后两个水珠的前后位置颜色要相同,问你可行吗?如果可行,把串的方法打印出来

思路 颜色作为节点,水珠为边建图。先用并查集判断连通性,再判断是否为欧拉图,最后dfs打印~注意无向图用过一条边i->j后,要删去i->j和j->i,还有打印的时候有小技巧,可以体会下~


#include <iostream>#include <cstdio>#include <cstring>#include <map>using namespace std;const int maxn = 51;int n,m;int g[maxn][maxn];int fa[maxn];int ra[maxn];int bian[maxn];int mapp[maxn];//原映射到新 int rmapp[maxn];int judge(int x){if(rmapp[x] == -1){rmapp[x] = n;mapp[n] = x;n++;}return rmapp[x];}int find(int x){if(x == fa[x])return x;return fa[x] = find(fa[x]);}void unin(int x,int y){x = find(x);y = find(y);if(x == y)return;if(ra[x] > ra[y]){fa[y] = x;}else if(ra[y]>ra[x]){fa[x] = y;}else{fa[x] = y;ra[y]++;}}void dfs(int i){for(int j=0;j<n;j++){while(g[i][j]){g[i][j]--;g[j][i]--;dfs(j);//可细考虑 printf("%d %d\n",mapp[j],mapp[i]);}}}int main(){int T;cin>>T;int t = 1;for(t=1;t<=T;t++){scanf("%d",&m);memset(g,0,sizeof(g));memset(ra,0,sizeof(ra));memset(bian,0,sizeof(bian));memset(rmapp,-1,sizeof(rmapp)); for(int i=1;i<=maxn;i++){fa[i] = i;}n = 0;for(int i =0;i<m;i++){int u,v;scanf("%d%d",&u,&v);u = judge(u);v = judge(v);unin(u,v);g[u][v]++;g[v][u]++;bian[u]++;bian[v]++;}bool flag = 0;if(bian[0]&1)flag = 1;for(int i=1;i<n&&flag==0;i++){if(find(i) != find(i-1))flag = 1;if(bian[i]&1)flag = 1;}if(flag){printf("Case #%d\nsome beads may be lost\n\n",t);continue;}printf("Case #%d\n",t);dfs(0);puts("");}}


0 0
原创粉丝点击