P1341 无序字母对(欧拉回路+并查集)
Posted greenofyu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1341 无序字母对(欧拉回路+并查集)相关的知识,希望对你有一定的参考价值。
1 //并查集判联通,dfs求解欧拉回路 2 #include<iostream> 3 using namespace std; 4 const int N=150; 5 int mp[N][N];//邻接矩阵存图 6 int d[N];//点的度数 7 char res[N*N];//大于C(52,1)*C(51,1)/2,边数 8 int n;//边数 9 void dfs(int now) 10 { 11 for(int i=‘A‘;i<=‘z‘;i++)//没什么好说的 12 { 13 if(mp[now][i]) 14 { 15 mp[now][i]=mp[i][now]=0; 16 dfs(i); 17 } 18 } 19 res[n--]=now;//走到底再存,得反过来,如果顺着来的话,数目有点麻烦(其实也是看别人反着来) 20 } 21 int fa[N]; 22 int finds(int x) 23 { 24 while(fa[x]!=x) 25 { 26 x=fa[x]; 27 } 28 return x; 29 } 30 int main(void) 31 { 32 cin>>n; 33 for(int i=‘A‘;i<=‘z‘;i++) 34 { 35 fa[i]=i; 36 }//并查集初始化 37 for(int i=1;i<=n;i++) 38 { 39 string s; 40 cin>>s; 41 mp[s[0]][s[1]]=mp[s[1]][s[0]]=1; 42 d[s[0]]++;//度数加一 43 d[s[1]]++; 44 45 int f1=finds(s[0]); 46 int f2=finds(s[1]); 47 fa[f1]=f2;//union 48 } 49 int cnt=0;//连通分量数 50 for(int i=‘A‘;i<=‘z‘;i++) 51 { 52 if(d[i]&&fa[i]==i) 53 { 54 cnt++; 55 } 56 } 57 if(cnt>1) 58 { 59 cout<<"No Solution"<<endl; 60 return 0; 61 } 62 cnt=0;//奇点数 63 int head=0;//欧拉回(通)路起点 64 for(int i=‘A‘;i<=‘z‘;i++) 65 { 66 if(d[i]&1) 67 { 68 cnt++; 69 if(head==0) 70 { 71 head=i; 72 } 73 } 74 } 75 if(cnt&&cnt!=2)//奇点只能没有或者有两个 76 { 77 cout<<"No Solution"<<endl; 78 return 0; 79 } 80 if(!head)//如果没有奇点就找个最小的偶度点出发,注意如果有奇点必须从奇点出发(错了贼久) 81 { 82 for(int i=‘A‘;i<=‘z‘;i++) 83 { 84 if(d[i]) 85 { 86 head=i; 87 break; 88 } 89 } 90 } 91 int tmp=n; 92 dfs(head); 93 for(int i=0;i<=tmp;i++) 94 { 95 cout<<res[i] ; 96 } 97 return 0; 98 }
以上是关于P1341 无序字母对(欧拉回路+并查集)的主要内容,如果未能解决你的问题,请参考以下文章