带权并查集求助
  • 板块题目总版
  • 楼主ppip嘟嘟嘟
  • 当前回复1
  • 已保存回复1
  • 发布时间2022/4/25 20:57
  • 上次更新2023/10/28 02:54:22
查看原帖
带权并查集求助
374433
ppip嘟嘟嘟楼主2022/4/25 20:57

Link

题目大意:给定一堆 (x,y,z)(1xn,1ym)(x,y,z)(1\leq x\leq n,1\leq y\leq m),表示 vx+vy+n=zv_x+v_{y+n}=z,问后面信息是否与前面有矛盾。

代码(删除了不必要元素):

#include <bits/stdc++.h>
using namespace std;
const int MAXN{1000};
int f[MAXN*2+5],dis[MAXN*2+5];
int getf(int x)
{
    if (f[f[x]]==f[x]) return f[x];
    getf(f[x]);
    dis[x]+=dis[f[x]];
    return f[x]=f[f[x]];
}
void merge(int x,int y,int z)
{
    dis[f[x]]=z-dis[x]+dis[y];
    f[f[x]]=f[y];
}
int main()
{
    int n,m,k;scanf("%d %d %d",&n,&m,&k);
    for (int i{1};i<=n+m;++i)
    {
        f[i]=i;
        dis[i]=0;
    }
    for (int i{1};i<=k;++i)
    {
        int x,y,z;
        scanf("%d %d %d",&x,&y,&z);
        if (getf(x)==getf(y+n)&&dis[x]-dis[y+n]!=z) {printf("No\n");return 0;
        else merge(x,y+n,z);
    }
    printf("Yes\n");
    return 0;
}

显然,这份代码维护 dis(x)=vxrootdis(x)=v_x-root。但是这样的话,这份代码不就是把输入的信息当成 vxvy+n=zv_x-v_{y+n}=z 来做的吗,为什么能 AC?

2022/4/25 20:57
加载中...