hdu 4619 Warm up 2(并查集活用)
周赛。
1 /*
2 比较简单的一题
3 由于
4 1、水平骨牌不能与水平骨牌相交,垂直骨牌也不能与垂直骨牌相交---即每边的端点最多只能与一边相连
5 2、对于环,因为是正方形棋盘,没有斜边,所以环的边数一定是负数
6 所以,基于这两点,可以用并查集找链与环,然后减去一半或一半减一的边即可
7 */
8 #include <cstdio>
9 #include <cstring>
10 #define N 1005
11 #define M 105
12
13 int a[M][M], ans[N*2];
14 int father[N*2];
15 int rank[N*2];
16 void Make_set(int x)
17 {
18 for(int i=1; i<=x; i++)
19 {
20 father[i] = i;
21 rank[i] = 0;
22 }
23 }
24 int find(int x)
25 {
26 if(x!=father[x])
27 father[x]=find(father[x]);
28 return father[x];
29 }
30 void Union(int x,int y)
31 {
32 x=find(x);
33 y=find(y);
34 if(x==y) return ;
35 if(rank[x]>rank[y])
36 father[y]=x;
37 else if(rank[x]<rank[y])
38 father[x]=y;
39 else {
40 rank[x]++;
41 father[y]=x;
42 }
43 }
44
45
46 int main()
47 {
48 int n, m, aa;
49 while(scanf("%d%d",&n,&m)!=EOF)
50 {
51 if(n==0 && m==0) break;
52 Make_set(n+m);
53 memset(a, 0, sizeof(a));
54 memset(ans, 0, sizeof(ans));
55 aa=0;
56 int x, y;
57 for(int i=1; i<=n; i++)
58 {
59 scanf("%d%d",&x,&y);
60 a[y][x] = i;
61 a[y][x+1] = i;
62 }
63 for(int i=n+1; i<=n+m; i++)
64 {
65 scanf("%d%d",&x,&y);
66 if(a[y][x]>0)
67 Union(a[y][x], i);
68 if(a[y+1][x]>0)
69 Union(a[y+1][x], i);
70
71 }
72 for(int i=1; i<=n+m; i++)
73 {
74 int t = find(i);
75 if(t!=i)
76 ans[t]++;
77 }
78 for(int i=1; i<=n+m; i++)
79 {
80 if(ans[i]>0)
81 {
82 ans[i]++;
83 aa += ((ans[i])/2);
84 }
85 }
86 printf("%d\n",m+n-aa);
87 }
88 return 0;
89 }
2 比较简单的一题
3 由于
4 1、水平骨牌不能与水平骨牌相交,垂直骨牌也不能与垂直骨牌相交---即每边的端点最多只能与一边相连
5 2、对于环,因为是正方形棋盘,没有斜边,所以环的边数一定是负数
6 所以,基于这两点,可以用并查集找链与环,然后减去一半或一半减一的边即可
7 */
8 #include <cstdio>
9 #include <cstring>
10 #define N 1005
11 #define M 105
12
13 int a[M][M], ans[N*2];
14 int father[N*2];
15 int rank[N*2];
16 void Make_set(int x)
17 {
18 for(int i=1; i<=x; i++)
19 {
20 father[i] = i;
21 rank[i] = 0;
22 }
23 }
24 int find(int x)
25 {
26 if(x!=father[x])
27 father[x]=find(father[x]);
28 return father[x];
29 }
30 void Union(int x,int y)
31 {
32 x=find(x);
33 y=find(y);
34 if(x==y) return ;
35 if(rank[x]>rank[y])
36 father[y]=x;
37 else if(rank[x]<rank[y])
38 father[x]=y;
39 else {
40 rank[x]++;
41 father[y]=x;
42 }
43 }
44
45
46 int main()
47 {
48 int n, m, aa;
49 while(scanf("%d%d",&n,&m)!=EOF)
50 {
51 if(n==0 && m==0) break;
52 Make_set(n+m);
53 memset(a, 0, sizeof(a));
54 memset(ans, 0, sizeof(ans));
55 aa=0;
56 int x, y;
57 for(int i=1; i<=n; i++)
58 {
59 scanf("%d%d",&x,&y);
60 a[y][x] = i;
61 a[y][x+1] = i;
62 }
63 for(int i=n+1; i<=n+m; i++)
64 {
65 scanf("%d%d",&x,&y);
66 if(a[y][x]>0)
67 Union(a[y][x], i);
68 if(a[y+1][x]>0)
69 Union(a[y+1][x], i);
70
71 }
72 for(int i=1; i<=n+m; i++)
73 {
74 int t = find(i);
75 if(t!=i)
76 ans[t]++;
77 }
78 for(int i=1; i<=n+m; i++)
79 {
80 if(ans[i]>0)
81 {
82 ans[i]++;
83 aa += ((ans[i])/2);
84 }
85 }
86 printf("%d\n",m+n-aa);
87 }
88 return 0;
89 }