题意:
有一个运动场,运动场的坐席是环形的,有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
", 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 }