bzoj 1202 并查集

  首先我们知道若干区间和信息,判断给出信息是否合法,可以用并查集维护,我们用dis[x]表示x到father[x]的距离为多少,即区间father[x]到x的长度,这样我们可以在路径压缩的时候维护dis,对于加进来的x,y区间,如果两点祖先不相同,那么合并,相同的话判断是否和已知的信息相符,这样就可以了。

  需要注意的是为了防止x==y的情况发生,对于区间1,2和3,3,本来是连通的区间,但是因为读入为闭区间,所以需要将y++来使得区间向连通。

/**************************************************************
    Problem: 1202
    User: BLADEVIL
    Language: C++
    Result: Accepted
    Time:224 ms
    Memory:808 kb
****************************************************************/
 
//By BLADEVIL
#include <cstdio>
#include <cstring>
#define maxn 200
 
using namespace std;
 
int n,m;
int father[maxn],dis[maxn];
 
int getfather(int x){
    if (!father[x]) return x;
    int tmp=getfather(father[x]);
    dis[x]+=dis[father[x]];
    return father[x]=tmp;
}
 
int main(){
    int task;
    scanf("%d",&task);
    while (task--){
        scanf("%d%d",&n,&m);
        int flag=0;
        memset(father,0,sizeof father);
        memset(dis,0,sizeof dis);
        while (m--){
            int x,y,z,fx,fy;
            scanf("%d%d%d",&x,&y,&z);
            if (flag) continue;
            y++;    
            fx=getfather(x); fy=getfather(y);
            if (fx!=fy) {
                father[fy]=fx; 
                dis[fy]=dis[x]+z-dis[y];
            } else if (dis[y]-dis[x]!=z) flag=1;
        }
        if (flag) printf("false
"); else printf("true
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/BLADEVIL/p/3568147.html