hdu3926 Hand in Hand 同构图

 1 #include<cstring>
 2 #include<cstdio>
 3 #include<algorithm>
 4 using namespace std;
 5 
 6 int pre[10100];
 7 struct e{
 8     int a, b;
 9 };
10 e s1[10010];
11 e s2[10010];
12 
13 int find(int x)
14 {
15     while (x != pre[x])
16         x = pre[x];
17     return x;
18 }
19 
20 int cmp(e a, e b){
21     if (a.a == b.a) return a.b>b.b;
22     else return a.a>b.a;
23 }
24 
25 void init(int n)
26 {
27     for (int i = 1; i <= n; i++)
28         pre[i] = i;
29 }
30 
31 int main()
32 {
33     int t, cas = 1;;
34     scanf("%d", &t);
35     while (t--)
36     {
37         for (int i = 1; i<10010; i++)
38         {
39             s1[i].a = 1; s1[i].b = 0;
40             s2[i].a = 1; s2[i].b = 0;//最开始每个都是独立的,默认为链
41         }
42         bool flag = false;
43         int n1, m1, n2, m2;
44 
45         scanf("%d%d", &n1, &m1);
46         init(n1);
47         for (int i = 0; i<m1; i++)
48         {
49             int a, b;
50             scanf("%d%d", &a, &b);
51             int dx = find(a);
52             int dy = find(b);
53             if (dx != dy)
54             {
55                 pre[dx] = dy;
56                 s1[dy].a += s1[dx].a;
57                 s1[dx].a = 0;//把拉手的孩子数量加起来,下同
58             }
59             else s1[dy].b = 1;//否则在dy这个位置成环
60         }
61 
62         scanf("%d%d", &n2, &m2);
63         init(n2);
64         for (int i = 0; i<m2; i++)
65         {
66             int a, b;
67             scanf("%d%d", &a, &b);
68             int dx = find(a);
69             int dy = find(b);
70             if (dx != dy)
71             {
72                 pre[dx] = dy;
73                 s2[dy].a += s2[dx].a;
74                 s2[dx].a = 0;
75             }
76             else s2[dy].b = 1;
77         }
78         if (n1 == n2){
79 
80             sort(s1 + 1, s1 + n1 + 1, cmp);
81             sort(s2 + 1, s2 + n2 + 1, cmp);//排序,若孩子的数量相同则对是否是环进行排序,这里要注意
82 
83             for (int i = 0; i<n1; i++)
84             if (s1[i].a != s2[i].a || s1[i].b != s2[i].b) {//判断数量,状态
85                 flag = true;
86                 break;
87             }
88         }
89         if (n1 != n2)    flag = true;
90 
91         if (flag)
92             printf("Case #%d: NO\n", cas++);
93         else 
94             printf("Case #%d: YES\n", cas++);
95     }
96     return 0;
97 }

 

转载于:https://www.cnblogs.com/ouyang_wsgwz/p/7481984.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值