NOI 食物鏈

         衆大牛盡情鄙視我吧,是的,我現在纔想到我還沒有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.                     

    

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章