专题四 第十一道题

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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值