衆大牛盡情鄙視我吧,是的,我現在纔想到我還沒有A掉食物鏈,於是很無語的去寫了,然後在很無語的來寫個blog.
原本看許多關於並查集的ppt的時候都舉了這個例子,一開始以爲要維護好多東西,就很煩很煩,然後又看到網上關於這道題的都寫得好複雜好複雜,(@.@),就以爲要維護好多東西。
the result is----- 我自己想了個ws並查集,A掉之後,以爲是多麼新奇的方法,發現網上很多都是這麼寫的(囧..........)
我還是厚着臉皮把我的solution貼上來吧。
其實很明顯,動物之間的關係只有三種,而且是有一定的疊加關係的,這裏的三種狀態直接用1,2,3表示即可。然後,會發現,如果A吃B ,從A 向B 連一條1的邊(被吃是2,同類是3),那麼在路徑壓縮的時候順便把這些值加起來,可以得到結論:如果x 向y 連了邊權爲c 的邊,case c mod 3 of 1:吃 2:被吃 0:同類。
然後並查集裸做就可以了。
program rq455;
const
opp:array[1..3]of longint=(2,1,3);
new1:array[2..6]of longint=(2,1,3,2,1);
new2:array[2..6]of longint=(1,3,2,1,3);
var
i,n,k,d,x,y,fx,fy:longint;
g,fa:array[0..60000]of longint;
ans:longint;
procedure inf;
begin
assign(input,'rq455.in');
assign(output,'rq455.out');
reset(input);rewrite(output);
end;
procedure ouf;
begin
close(input);close(output);
end;
procedure link(x,y,z:longint);
var w:longint;
begin
fa[x]:=y; g[x]:=z;
end;
function find(x:longint):longint;
var k:longint;
begin
if fa[x]<>x then
begin
k:=find(fa[x]);
g[x]:=(g[x]+g[fa[x]]-1) mod 3+1;
fa[x]:=k;
end;
exit(fa[x]);
end;
procedure main;
begin
read(n,k);
for i:=1 to n do begin fa[i]:=i; g[i]:=3; end;
for k:=1 to k do
begin
read(d,x,y);
if (x>n) or (y>n ) then inc(ans)
else if (d=2)and (x=y) then inc(ans)
else
begin
if d=2 then
begin
fx:=find(X); fy:=find(y);
if fx<>fy then
link(fx,fy,new1[g[x]+opp[g[y]]])
else if (g[x]+opp[g[y]]) mod 3<>1 then
inc(ans);
end
else
if d=1 then
begin
fx:=find(x); fy:=find(y);
if fx<>fy then
link(fx,fy,new2[g[x]+opp[g[y]]])
else if (g[x]+opp[g[y]]) mod 3<>0 then
inc(ans);
end;
end;
end;
write(ans);
end;
begin
inf;
main;
ouf;
end.