Hihocoder #1515 : 分数调查

#1515 : 分数调查

 
  带权并查集。
 
 1 /*
 2 如果把每个人抽象成一个点,之间的关系抽象成边。
 3 那么如果询问的两个人之间存在关系,说明,他们在图上上是联通的。
 4 所以并查集维护一下连通性。
 5 对于分数之间的关系,用到带权并查集。
 6 每个点里存一个val表示当前点的分数-根节点的分数。
 7 查询:
 8 xy不连通,输出-1,
 9 否则val[x]=fen[x]-fen[u],val[y]=fen[y]-fen[u],输出fen[x]-fen[y]=val[x]-val[y]
10 合并:
11 x的根节点为u,y的根节点为v,fa[u]=v;
12 更新后的val[u]=fen[u]-fen[v],
13 val[x]=fen[x]-fen[u]  ->  fen[u]=fen[x]-val[x]
14 val[y]=fen[y]-fen[v]  ->  fen[v]=fen[y]-val[y]
15 fen[u]-fen[v] = fen[x] - fen[y] + val[y] - val[x] = S + val[y] - val[x]
16 */
17 #include<bits/stdc++.h>
18 using namespace std;
19 typedef long long LL;
20 
21 inline int read() {
22     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
23     for (;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
24 }
25 
26 const int N = 100010;
27 int fa[N],val[N];
28 
29 int find(int x) {
30     if (x == fa[x]) return x;
31     int tmp = find(fa[x]);
32     val[x] += val[fa[x]];
33     fa[x] = tmp;
34     return fa[x];
35 }
36 int main() {
37     int n = read(), m = read(), k = read();
38     for (int i=0; i<=n; ++i) 
39         fa[i] = i, val[i] = 0;
40     for (int i=1; i<=m; ++i) {
41         int x = read(),y = read(),S = read();
42         int u = find(x),v = find(y);
43         if (u != v) {
44             fa[u] = v;
45             val[u] = val[y] - val[x] + S;
46         }
47     }
48     while (k--) {
49         int x = read(),y = read();
50         if (find(x) != find(y)) puts("-1");
51         else {
52             printf("%d\n",val[x]-val[y]);
53         }
54     }
55     return 0;
56 }

猜你喜欢

转载自www.cnblogs.com/mjtcn/p/9755169.html
今日推荐