BZOJ1202 [HNOI2005]狡猾的商人 并查集+前缀和

有一个长为n的数列,给出m个子段和信息,问是否一定存在冲突。数列可以为负。
这个题用并查集做感觉很玄学
按照题解打了一遍还是不太清晰
https://www.cnblogs.com/FallDream/p/bzoj1202.html
这篇题解思路比较好
建图,并且插入反边,bfs判断一个点的距离是否不唯一

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
#define clr(x,i) memset(x,i,sizeof(x)) 
using namespace std;
const int N=105;
int n,m,fa[N],sum[N],flag,t;
int find(int x)
{
    if(fa[x]==x)return x;
    int ff=fa[x];
    fa[x]=find(fa[x]);
    sum[x]+=sum[ff];
    return fa[x];
}
void work(int a,int b,int w)
{
    int x=find(a),y=find(b);
    if(x!=y){
        fa[x]=y;
        sum[x]=sum[b]-sum[a]-w;
    }
    else if(sum[b]-sum[a]!=w)
      flag=1;
}
void solve()
{
    scanf("%d%d",&n,&m);
    clr(sum,0);flag=0;
    for(int i=0;i<=n;i++)
      fa[i]=i;
    for(int i=1;i<=m;i++)
    {
        int s,t,w;
        scanf("%d%d%d",&s,&t,&w);
        work(s-1,t,w);
        if(flag)break;
    }
    if(flag)printf("false\n");
    else printf("true\n");
}
int main()
{
    int cas;scanf("%d",&cas);
    while(cas--)solve();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/wolf_reiser/article/details/78942605