1 题目编号:1023
2 题目内容:
3 解题思路形成过程:这是一道并查集题目。
(1)弄清题意,找出出现冲突的位置,判断冲突很简单就是当两个人在同一行坐,同时他们到根节点的距离差值正好是他们之间的差值,此时就出现了冲突了。
(2)关键有两个地方,这也是并查集题目的难点,就是压缩集合,和求节点到根的距离。这里压缩集合就很简单了,一个通用的递归。求到跟的距离dist[a] += dist[tem]; dist[rb]=dist[a]+x-dist[b];这两行代码是核心代码,第一行是求出节点a到根的距离。
4 代码:
#include
#include
#include
#include
#define MAXNUM 50005
using namespace std;
//father:存储的是节点的父节点的下标,dist存储的是相对于父节点的距离
int father[MAXNUM],dist[MAXNUM];
int n,m;
int find_father(int a)
{
if(father[a]==a)return a;
int tem = father[a];
father[a]=find_father(father[a]);
dist[a] += dist[tem];
return father[a];
}
void union_set(int a,int b,int x)
{
int ra = find_father(a);
int rb = find_father(b);
father[rb]=ra;
dist[rb]=dist[a]+x-dist[b];
}
int main()
{
int a,b,ra,rb,x,conflics;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(dist,0,sizeof(dist));
for(int i=0;i<=n;i++)
father[i]=i;
conflics=0;
for(int i=0;i
scanf("%d%d%d",&a,&b,&x);
ra = find_father(a);
rb = find_father(b);
if(ra==rb)
{
if(dist[b]-dist[a]!=x)conflics++;
}
if(ra!=rb)union_set(a,b,x);
}
printf("%d\n",conflics);
}
return 0;
}