1. 程式人生 > >hdu-1116(歐拉回路+並查集)

hdu-1116(歐拉回路+並查集)

題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=1116

思路:將字串的頭元素和尾元素視為圖的x,y節點,然後合併x,y。

如果這個圖不連通,則門不能開啟,如果路徑是歐拉回路或者尤拉通路,則門可以開啟。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int a[50],b[50],vis[50],in[50],out[50];
char str[1200];
int f(int x)
{
    if(x==a[x]) return
a[x]; else { a[x]=f(a[x]); return a[x]; } } void Merge(int x,int y) { int t1=f(x),t2=f(y); if(t1!=t2) { a[t2]=t1; } } int main(void) { int num,i,j,x,y,t,n; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i=0
;i<26;i++) { a[i]=i;vis[i]=0; b[i]=0;in[i]=0;out[i]=0; } for(j=0;j<n;j++) { scanf("%s",str); x=str[0]-'a'; y=str[strlen(str)-1]-'a'; Merge(x,y); in[y]++;out[x]++; vis[x]=1;vis[y]=1
; } for(i=0;i<26;i++) a[i]=f(i); num=0; for(i=0;i<26;i++) if(vis[i]&&a[i]==i) num++; if(num>1) { printf("The door cannot be opened.\n"); } else { num=0; for(i=0;i<26;i++) if(vis[i]&&in[i]!=out[i]) b[num++]=i; if(num==0) { printf("Ordering is possible.\n"); } else if(num==2&&(out[b[0]]-in[b[0]]==1&&in[b[1]]-out[b[1]]==1|| out[b[1]]-in[b[1]]==1&&in[b[0]]-out[b[0]]==1)) printf("Ordering is possible.\n"); else printf("The door cannot be opened.\n"); } } return 0; }