中南大学第十一届大学生程序设计竞赛-COJ1904-精灵的交际网

1904: 精灵的交际网

Submit Page Summary Time Limit: 1 Sec Memory Limit: 128 Mb Submitted: 12 Solved: 2
Description
天才少女科学家Cicini正在研究某种罕见的精灵的交际行为。她认为这些精灵只会与自己性别相反的精灵发生谈话,这些精灵一共也只有两种性别。在她的实验之中,由于每一个精灵的翅膀上都被写上了序号,因此每一个个体都是可以相互区分的。但是由于她的女仆Syaro带着Cicini和Cicini的朋友们一起开心的度过了万圣节,导致Cicini的实验报告在某一条实验记录后开始发生错误了,现在请你找出一定会出现性别冲突的第一条错误的实验记录出现在哪里。

Input
第一行是一个数据组数t,对于每一组数据,第一行是有两个整数n和k,(n,k<=50000) ,表示在这一次实验中一共使用了n只精灵以及有k条实验记录,接下来k行,每一行有两个正整数数a和b,表示精灵a和b发生了谈话。(a,b<=n , a!=b)

Output
对于每一组数据,输出第一条错误的实验记录的位置,假若到最后都未发现错误,则输出-1

Sample Input
2
3 3
1 2
2 3
1 3
4 2
1 2
3 4
Sample Output
3
-1
Hint
Source
中南大学第十一届大学生程序设计竞赛

Author
Forget_ever

题目大意:在不确定所有精灵的性别的情况下,找出在哪一个位置一定发生性别冲突。
解题思路:用并查集,有确定的关系才加边,维护孩子与父亲的关系。
考查内容:并查集
时间复杂度: O(n)
题目难度:★★

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
const int MAXN=50005;
int f[MAXN],r[MAXN];

void init(int n)
{
    for(int i=0;i<=n;i++)
        f[i]=i,r[i]=0;//0同性 1异性
}

int Find(int v)
{
    if(v==f[v]) return v;
    else
    {
        int rt=Find(f[v]);
        r[v]=r[v]^r[f[v]];
        return f[v]=rt;
    }
}

void Merge(int x,int y)
{
    int fx=Find(x);
    int fy=Find(y);
    /*
    x->fx  y->fy
    r[x]  r[y]  r[fx] x fx y fy
    0      0     1    a a  b b
    0      1     0    a a  b a
    1      0     0    a b  b b
    1      1     1    a b  b a
    */
    f[fx]=fy;
    r[fx]=(!(r[x]^r[y]));
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int T;
    cin>>T;
    int cas=1;
    while(T--)
    {
        int n,m;
        cin>>n>>m;
        init(n);
        int x,y;
        bool flag=false;
        int cnt=0;
        for(int i=1;i<=m;i++)
        {
            cin>>x>>y;
            int fx=Find(x),fy=Find(y);
            if(flag) continue;
            if(fx==fy&&r[x]==r[y])
            {
                flag=true;
                cnt=i;
            }
            if(fx!=fy)  Merge(x,y);
        }
        if(flag)  cout<<cnt<<endl;
        else  cout<<"-1"<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值