题意:调查一种虫子的性行为,先假定虫子里没有同性恋。每一次测试输入N只虫,然后输入M个数对( x, y ),表示 x, y 之间有性行为, 最后判断假设成立与否(即判断有没有同性恋)。
分析:这题的题目好污啊,看得我都羞羞了~~
恩如果你脑袋里装的还是那些东西的话我建议你过一会再来看。
首先我们假设虫子里没有同性恋,也就是说若虫子1与虫子2、3有关系则2和3必为同性且和1为异性,那么就可以把2和3进行合并,这里合并用到的是并查集,时间复杂度只有O(1),不会的自己去网上找资料。也就是说把所有和某条虫发生过关系的虫子全部合并。最后我们来判断:若假设不成立也就是没有同性恋,那么任意发生过关系的两条虫一定会在两个不同的集合内,若不满足这一项,则说明这里面有同性恋。
代码:
var l,t,n,m,x,y,i:longint; a:array[0..2000000,1..2] of longint; f:array[1..2000] of longint; flag:boolean; procedure qsort(l,r:longint); var i,j,k:longint; begin if l>=r then exit; i:=l; j:=r; k:=a[(i+j) div 2,1]; repeat while a[i,1]<k do inc(i); while a[j,1]>k do dec(j); if i<=j then begin a[0]:=a[i];a[i]:=a[j];a[j]:=a[0]; inc(i);dec(j); end; until i>j; qsort(i,r); qsort(l,j); end; function find(x:longint):longint; begin if f[x]=x then exit(x); find:=find(f[x]); f[x]:=find; end; begin readln(t); for l:=1 to t do begin if l>1 then writeln; writeln('Scenario #',l,':'); readln(n,m); for i:=1 to m do begin readln(x,y); a[i*2-1,1]:=x; a[i*2-1,2]:=y; a[i*2,1]:=y; a[i*2,2]:=x; end; qsort(1,m*2); a[0,1]:=0; for i:=1 to n do f[i]:=i; for i:=1 to m*2 do if a[i,1]<>a[i-1,1] then x:=a[i,2] else if find(a[i,2])<>find(x) then f[find(a[i,2])]:=find(x); flag:=true; for i:=1 to m*2 do if find(a[i,1])=find(a[i,2]) then begin writeln('Suspicious bugs found!'); flag:=false; break; end; if flag then writeln('No suspicious bugs found!'); end; end.