hihocoder #1515 : 分数调查 并查集好题

来源:互联网 发布:spss软件的作用 编辑:程序博客网 时间:2024/05/04 15:47

1515 : 分数调查

时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
小Hi的学校总共有N名学生,编号1-N。学校刚刚进行了一场全校的古诗文水平测验。

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

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

输入
第一行包含三个整数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

数据保证没有矛盾。

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

样例输入
10 5 3
1 2 10
2 3 10
4 5 -10
5 6 -10
2 5 10
1 10
1 5
3 5
样例输出
-1
20
0

做了这个题 发现以前的并查集白学了 - -

维护一个并查集
让每个集合的点 存的都是它与头点的差值。
这样 如果在一个集合 则直接相减就好

所以 在添加节点的时候,要维护每个位置存的值是与根点的差值

#include <iostream>#include <cmath>#include <iomanip>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int tag[2000005],d[2000005];int bing(int x){    while(tag[x]!=x)    {        x=tag[x];    }    return x;}void sbing(int x){    int y=tag[x];    if(tag[x]!=bing(x)) sbing(tag[x]);    {        tag[x]=bing(x);        d[x]=d[y]+d[x];    }}int main(){    int n,m,q;    while(cin>>n>>m>>q)    {        for(int i=0;i<=n;i++) tag[i]=i;        memset(d,0,sizeof(d));        int x,y,z;        for(int i=0;i<m;i++)        {            cin>>x>>y>>z;            int fx=bing(x);            int fy=bing(y);            sbing(x);            sbing(y);            tag[fy]=fx;            d[fy]=d[x]-(d[y]+z);        }        for(int i=0;i<=n;i++)            sbing(i);        for(int i=0;i<q;i++)        {            cin>>x>>y;            if(bing(x)!=bing(y))            {                cout<<"-1"<<endl;            }            else            {                cout<<d[x]-d[y]<<endl;            }        }    }}
0 0