1. 程式人生 > >中南大學第十一屆大學生程式設計競賽-COJ1904-精靈的交際網

中南大學第十一屆大學生程式設計競賽-COJ1904-精靈的交際網

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