[HNOI2005]狡猾的商人 带权并查集

来源:互联网 发布:淘宝店铺综合排名查询 编辑:程序博客网 时间:2024/05/20 16:10

给定m个区间和,问是否有矛盾

复习一下,带权并查集保存着这个元素与祖先的关系

在合并的过程中就像向量合并一样,可以画出x->fa[x],y->fa[y],x->y这样的图方便理解

这篇文章解释得很清楚NOIAu

//#include<iostream>#include<stdio.h>#include<algorithm>#include<queue>#include<string.h>#include<math.h>#include<set>#include<map>#include<vector>#include<iomanip>#include<stack>using namespace std;#define ll long long#define ull unsigned long long#define pb push_back#define mem(a) memset(a,0,sizeof a)#define FOR(a) for(int i=1;i<=a;i++) const int maxn=1e2+7; int fa[maxn],v[maxn],flag,t; int find(int x){    if(fa[x]==x)return x;    t=find(fa[x]);    v[x]+=v[fa[x]];    fa[x]=t;    return fa[x];} void work(int x,int y,int w){    int p=find(x),q=find(y);    if(p!=q){        fa[p]=q;        v[p]=v[y]-v[x]-w;    }else if(v[y]-v[x]!=w)flag=1;} int main(){    int w,n,m;scanf("%d",&w);    while(w--){        memset(v,0,sizeof v);        flag=0;        scanf("%d%d",&n,&m);        for(int i=0;i<=n;i++)fa[i]=i;        for(int i=1;i<=m;i++){            int x,y,z;scanf("%d%d%d",&x,&y,&z);            if(!flag)work(x-1,y,z);        }        if(flag)printf("false\n");else printf("true\n");    }}



阅读全文
0 0
原创粉丝点击