HDU 3038 How Many Answers Are Wrong (并查集好题)(带权并查集)

来源:互联网 发布:nginx 账号密码 编辑:程序博客网 时间:2024/05/11 13:04

这道题给了你很多带值的区间,a到b的和为c,问你有几条是假的。

在并查集的基础上附加上值,这样在路径压缩的时候也要更新节点到father的和。

对于计算dis还有一些疑惑,想了半天,还是先做下一题吧~

#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespace std;const int maxn = 1e5+5;int father[maxn],dis[maxn],n,m,ans;int query(int x) {    if(x != father[x]) {        int per = father[x];        father[x] = query(father[x]);        dis[x] += dis[per]; // 路径压缩的时候吧 x到father[x]的距离也加起来    }    return father[x];}void merge(int x,int y,int z) {    int a = query(x);    int b = query(y);    if(a < b) {        father[b] = a;        dis[b] = dis[x] - dis[y] + z; /这里还是有些不理解    }    else if(a > b) {        father[a] = b;        dis[a] = -(dis[x] - dis[y] + z);    }    else {        if(dis[y] - dis[x] != z)            ans++;    }}int main() {    while(scanf("%d%d",&n,&m) != EOF) {        ans = 0;        for(int i = 0;i <= n;i++) {            father[i] = i;            dis[i] = 0;        }        for(int i = 1;i <= m;i++) {            int x,y,z;            scanf("%d%d%d",&x,&y,&z);            x--;            merge(x,y,z);        }        printf("%d\n",ans);    }}


0 0
原创粉丝点击