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.                     

    

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