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 }

 

posted @ 2020-05-07 22:55  White_Li  阅读(154)  评论(0)    收藏  举报