您的位置:首页 > 其它

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

2016-07-20 15:30 393 查看
这道题给了你很多带值的区间,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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  路径压缩 并查集