hdu 3047 Zjnu Stadium(加权并查集)2009 Multi-University Training Contest 14

题意:

有一个运动场,运动场的坐席是环形的,有1~300共300列座位,每列按有无限个座位计算T_T。

 

输入:

有多组输入样例,每组样例首行包含两个正整数n, m。分别表示共有n个人,m次操作。

接下来m行,每行包含a, b, x三个整数,表示a在b右边x个位置。

 

输出:

如果a,b的关系已经存在,新操作如果获得的位置关系与已存在的关系不同,则ans+1。输出ans,每组输出占一行。

 

用加权并查集可以解决。权值存在val[]数组里,val[i]的含义为从i到根节点的距离。

由于是一个长度为300的环形座位,所以每次算得的结果都需要mod 300(然而实际上不mod 300也可以ac)。

 

具体见代码——

 1 #include <cstdio>
 2 #include <cmath>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 const int N = 50010;
 8 const int M = 300;
 9 
10 int fm[N], val[N];
11 int a, b, x;
12 int n, m;
13 int ans;
14 
15 void init()
16 {
17     for(int i = 1; i <= n; i++)
18     {
19         fm[i] = i;
20         val[i] = 0;
21     }
22     ans = 0;
23 }
24 
25 int mfind(int x)
26 {
27     if(x == fm[x]) return x;
28     int t = fm[x];
29     fm[x] = mfind(fm[x]);
30     val[x] += val[t];
31     val[x] %= M;
32     return fm[x];
33 }
34 
35 void mmerge()
36 {
37     int fx = mfind(a);
38     int fy = mfind(b);
39     if(fx != fy)
40     {
41         fm[fx] = fy;
42         val[fx] += val[b]-val[a]+x;             //由于需要获得的是从fx到fy的距离,所以需要以b与a的相对距离再加上x
43         val[fx] %= M;
44     }
45     else
46     {
47         if((val[a]-val[b]+M)%M != x%M) ans++;       
48     }
49 }
50 
51 void work()
52 {
53     while(m--)
54     {
55         scanf("%d%d%d", &a, &b, &x);
56         mmerge();
57     }
58     printf("%d\n", ans);
59 }
60 
61 int main()
62 {
63     //freopen("test.in", "r", stdin);
64     while(~scanf("%d%d", &n, &m))
65     {
66         init();
67         work();
68     }
69     return 0;
70 }
View Code

 

posted @ 2015-08-22 17:11  mypride  阅读(197)  评论(0编辑  收藏  举报