题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3038
题意:给出两个数N和M代表有N个数个M组数据
N个数是未知的,然后M组数据每组数据形如:l r x
代表位置l和位置r之间的数的和为x,最后求出M组数据中有
几组是与上面冲突的。
分析:这道题我直接就知道是带权并查集的题,原因是我直接按带权并查
集找的题,所以在这不能为诸君讲述有此类题如何联系到并查集的过程。
直接说方法吧,首先定义数据level【maxn】存相权值初始化为0,level【x】代表0-x之间
所有数的和,如果level【r】-level【l】!=x则表示有冲突
现上代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxh=200000+10;
int fa[maxh],level[maxh],n,m;
void Init(int num)
{
for(int i=0;i<=num;i++)
{
fa[i]=i;
level[i]=0;
}
}
int Find(int x)
{
if(x!=fa[x])
{
int tmp=Find(fa[x]);
level[x]=level[x]+level[fa[x]];
fa[x]=tmp;
}
return fa[x];
}
bool Union(int x,int y,int type)
{
int fx=Find(x);
int fy=Find(y);
if(fx==fy)
{
if(level[x]+type==level[y])
return true;
return false;
}
else
{
fa[fy]=fx;
level[fy]=level[x]-level[y]+type;
return true;
}
}
int main()
{
int x,y,type,sum;
while(~scanf("%d%d",&n,&m))
{
Init(n);
sum=0;
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&x,&y,&type);
x--;
if(!Union(x,y,type))
sum++;
}
printf("%d\n",sum);
}
return 0;
}