HihoCoder

小Hi的学校总共有N名学生,编号1-N。学校刚刚进行了一场全校的古诗文水平测验。  

学校没有公布测验的成绩,所以小Hi只能得到一些小道消息,例如X号同学的分数比Y号同学的分数高S分。  

小Hi想知道利用这些消息,能不能判断出某两位同学之间的分数高低?

Input

第一行包含三个整数N, M和Q。N表示学生总数,M表示小Hi知道消息的总数,Q表示小Hi想询问的数量。  

以下M行每行三个整数,X, Y和S。表示X号同学的分数比Y号同学的分数高S分。  

以下Q行每行两个整数,X和Y。表示小Hi想知道X号同学的分数比Y号同学的分数高几分。  

对于50%的数据,1 <= N, M, Q <= 1000  

对于100%的数据,1 <= N, M, Q<= 100000 1 <= X, Y <= N -1000 <= S <= 1000

数据保证没有矛盾。

Output

对于每个询问,如果不能判断出X比Y高几分输出-1。否则输出X比Y高的分数。

Sample Input

10 5 3  
1 2 10  
2 3 10  
4 5 -10  
5 6 -10  
2 5 10  
1 10  
1 5  
3 5

Sample Output

-1  
20  
0


带权并查集的典型运用

#include<cstdio>
#include <cmath>
#include <queue>
#include <stdlib.h>
#include<iostream>
#include<cstring>
#include <vector>
using namespace std;
const int MAXN=100000+10;
int F[MAXN];
int val[MAXN];
int Find(int x)
{
  if(F[x]==-1||F[x]==x)return x;
  int tmp=Find(F[x]);
  val[x]+=val[F[x]];
  return F[x]=tmp;
}
int main()
{
    int n,m,q,a,b,c;
    while(scanf("%d%d%d",&n,&m,&q)!=EOF)
    {
         for(int i=1;i<=n;i++)
         {
             F[i]=-1;
             val[i]=0;
         }
        while(m--)
        {
            scanf("%d%d%d",&a,&b,&c);
            int t1=Find(a);
            int t2=Find(b);
            F[t2]=t1;
            val[t2]=val[a]-val[b]-c;
        }
        while(q--)
        {
            scanf("%d%d",&a,&b);
            int t1=Find(a);
            int t2=Find(b);
            if(t1!=t2)puts("-1");
           else printf("%d
",val[a]-val[b]);
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/a249189046/p/8168332.html