hdu 1512 并查集

又是基于连通性的问题,可以用并查集来解决,每个集合都维护一个优先队列,合并的时候按照优先队列的大小启发式合并即可。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <queue>
 5 using namespace std;
 6 
 7 const int N = 100001;
 8 int f[N];
 9 priority_queue<int> q[N];
10 int n, m;
11 
12 void init()
13 {
14     for ( int i = 1; i <= n; i++ )
15     {
16         f[i] = i;
17         while ( !q[i].empty() ) q[i].pop();
18     }
19 }
20 
21 int findf( int x )
22 {
23     if ( f[x] != x ) f[x] = findf( f[x] );
24     return f[x];
25 }
26 
27 int union_set( int x, int y )
28 {
29     x = findf(x), y = findf(y);
30     if ( x == y ) return -1;
31     int sx = q[x].top();
32     q[x].pop();
33     sx >>= 1;
34     int sy = q[y].top();
35     q[y].pop();
36     sy >>= 1;
37     if ( q[x].size() > q[y].size() ) swap( x, y );
38     f[x] = y;
39     while ( !q[x].empty() )
40     {
41         int nn = q[x].top();
42         q[x].pop();
43         q[y].push(nn);
44     }
45     q[y].push(sx);
46     q[y].push(sy);
47     return q[y].top();
48 }
49 
50 int main ()
51 {
52     while ( scanf("%d", &n) != EOF )
53     {
54         init();
55         for ( int i = 1; i <= n; i++ )
56         {
57             int tmp;
58             scanf("%d", &tmp);
59             q[i].push(tmp);
60         }
61         scanf("%d", &m);
62         while ( m-- )
63         {
64             int u, v;
65             scanf("%d%d", &u, &v);
66             printf("%d
", union_set( u, v ));
67         }
68     }
69     return 0;
70 }
原文地址:https://www.cnblogs.com/huoxiayu/p/4780216.html