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