1.题目编号:1023
2.简单题意:在2007年第十二届浙江大学生运动会,在浙江师范大学有一个新的体育场建成。这是一个可以容纳成千上万人的现代体育场。观众席作了一个圆,列的总数为300,编号为1—300,计数顺时针,我们假设行数是无限的。这些天,Busoniya想在这个体育场举行大型文艺演出。将会有n个人去那里,编号为1到n,Busoniya已经预订了几个座位。为了让它有趣,他为这些座位提了M个要求:A B X,这意味着编号B的人必须坐在编号为A的顺时针X距离。例如:A是在第四列,X是2,那么B必须在第六列(6 = 4 + 2)。你的判断的规则很容易:当一个新的要求与前述的冲突,我们定义它为不正确的,否则它是正确的。请找出所有不正确的请求,并将它们计数为R。
3.解题思路形成过程:这是一个并查集问题。找出有冲突的位置,即当两个人在同一行坐,他们到根节点的距离差值正好就是他们之间的差值就冲突,然后找出并查集。
4.感悟:用到了数学的向量知识
5.AC的代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXX 50002
using namespace std;
int father[MAXX],dist[MAXX];
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(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,r;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(dist,0,sizeof(dist));
for(int i=0;i<=n;i++)
father[i]=i;
r=0;
for(int i=0;i<m;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)
r++;
}
if(ra!=rb)
Union(a,b,x);
}
printf("%d\n",r);
}
return 0;
}