HDU3926
因为每个点最大度为2,可以想象一下,每个连通分量一定是一个环或者一条没有支路的链
因此我们可以记录一个连通分量是链还是环,以及有包含了多少点,就可以确定一个连通分量的所有性质
并查集求出所有联通分量以后优先按点数排序再按类型排序,两个图逐一比较即可
至于怎么求连通分量:
1. 维护每个点的祖先,以及以他为根的子树中的节点个数
2. 两个点之间连边,那么就把两个点合并。这里需要注意,一定是将节点个数小的点合并到节点个数大的点上,为什么呢,因为这样才可以保证合并是有序的(这里我没想到什么比较好的讲法,其实想象一下就明白了),第二个注意点,在合并之前,如果发现两个点的祖先相同,那么就说明有环,这时候只需要把这个联通分量标成是环的类型就行了,不用合并(比如1-2一条边,2-1一条边,合并两次的话,连通分量节点个数就错了)
代码写的很丑,细节算比较多的一个题,wa了好几发
1 #include<iostream> 2 #include<algorithm> 3 #include<string.h> 4 using namespace std; 5 struct node{ 6 int cnt,tp; 7 bool operator < (const node &a){ 8 if (cnt==a.cnt) return tp<a.tp; 9 return cnt<a.cnt; 10 } 11 }a[10010],g[10010]; 12 int na,ma,ng,mg,u,v,q,fa[10010],fg[10010],sa[10010],sg[10010],ta[10010],tg[10010],f; 13 14 void ini(){ 15 for (int i=0;i<10010;i++){ 16 fa[i]=fg[i]=i; 17 sa[i]=sg[i]=1; 18 } 19 memset(ta,0,sizeof ta); 20 memset(tg,0,sizeof tg); 21 f=1; 22 } 23 24 int getfa(int u){ 25 return fa[u]==u?fa[u]:fa[u]=getfa(fa[u]); 26 } 27 28 int getfg(int u){ 29 return fg[u]==u?fg[u]:fg[u]=getfg(fg[u]); 30 } 31 32 void mergea(int u,int v){ 33 if (getfa(v)==getfa(u)){ 34 ta[getfa(u)]=1; 35 return; 36 } 37 if (sa[getfa(u)]>=sa[getfa(v)]){ 38 fa[getfa(v)]=getfa(u); 39 sa[getfa(u)]+=sa[getfa(v)]; 40 } 41 else{ 42 fa[getfa(u)]=getfa(v); 43 sa[getfa(v)]+=sa[getfa(u)]; 44 } 45 } 46 47 void mergeg(int u,int v){ 48 if (getfg(v)==getfg(u)){ 49 tg[getfg(u)]=1; 50 return; 51 } 52 if (sg[getfg(u)]>=sg[getfg(v)]){ 53 fg[getfg(v)]=getfg(u); 54 sg[getfg(u)]+=sg[getfg(v)]; 55 } 56 else{ 57 fg[getfg(u)]=getfg(v); 58 sg[getfg(v)]+=sg[getfg(u)]; 59 } 60 } 61 62 int main() 63 { 64 cin>>q; 65 for (int t=1;t<=q;t++){ 66 ini(); 67 cin>>na>>ma; 68 while (ma--){ 69 cin>>u>>v; 70 mergea(u,v); 71 } 72 for (int i=1;i<=na;i++) a[i]={sa[i],ta[i]}; 73 cin>>ng>>mg; 74 while (mg--){ 75 cin>>u>>v; 76 mergeg(u,v); 77 } 78 for (int i=1;i<=ng;i++) g[i]={sg[i],tg[i]}; 79 if (na!=ng || ma!=mg) f=0; 80 if (f){ 81 sort(a+1,a+1+na); 82 sort(g+1,g+1+ng); 83 for (int i=1;i<=na && f;i++){ 84 if (a[i].cnt!=g[i].cnt || a[i].tp!=g[i].tp) f=0; 85 } 86 } 87 cout<<"Case #"<<t<<": "; 88 if (f) cout<<"YES"<<endl; 89 else cout<<"NO"<<endl; 90 } 91 return 0; 92 }

浙公网安备 33010602011771号