种类并查集的经典题目,和NOIP2010里的关押罪犯一个类型,0,1,2表示三个种类,在合并时用类似向量的方法去导公式,其他的模拟操作即可。
View Code
1 program pku1182(input,output); 2 var 3 father,r : array[0..50000] of longint; 4 i,n,x,y,answer,k,t : longint; 5 function find(i : longint):longint; 6 var 7 temp:longint; 8 begin 9 if father[i]=i then 10 exit(i); 11 temp:=father[i]; 12 father[i]:=find(father[i]); 13 r[i]:=(r[temp]+r[i]) mod 3; 14 exit(father[i]); 15 end; 16 procedure union(x,y,h:longint); 17 var 18 a,b:longint; 19 begin 20 a:=find(x); 21 b:=find(y); 22 father[a]:=b; 23 r[a]:=(r[y]+h-r[x]+3) mod 3; 24 end; 25 begin 26 answer:=0; 27 readln(n,k); 28 for i:=1 to n do 29 father[i]:=i; 30 for i:=1 to k do 31 begin 32 readln(t,x,y); 33 if (x>n)or(y>n) then 34 begin 35 inc(answer); 36 continue; 37 end; 38 case t of 39 1:if find(x)=find(y) then 40 begin 41 if r[x]<>r[y] then 42 inc(answer) 43 end 44 else 45 union(x,y,0); 46 2:begin 47 if x=y then 48 begin 49 inc(answer); 50 continue; 51 end; 52 if find(x)=find(y) then 53 begin 54 if r[x]<>(r[y]+1) mod 3 then 55 inc(answer) 56 end 57 else 58 union(x,y,1); 59 end; 60 end; 61 end; 62 writeln(answer); 63 end.