zoukankan      html  css  js  c++  java
  • uva11987 并查集小技巧

    大意:维护一种数据结构,支持 几乎是常数级别的 集合合并、将一个元素转移到另一个集合、询问每个集合的和与元素个数。

    思路:使用并查集,转移元素时留下一个空节点,同时增加一个节点,将p转移到新根。用pos[p]记录p数字现在的实际位置即可。

    program p11987;
    
    Var
     n,m,i,p,q,op,top:longint;
     f,c,pos,s:array[0..500002] of longint;
    
    Function find(P:longint):longint;
      begin
      if f[p]=p then exit(p);
      f[p]:=find(f[p]);
      exit(f[p]);
    end;
    
    Procedure union(p,q:longint);
    var
     fp,fq:longint;
      begin
      fp:=find(pos[p]);
      fq:=find(pos[q]);       
      if fp=fq then exit;
      if c[fp]<c[fq] then
        begin
        f[fp]:=fq;
        inc(c[fq],c[fp]);
        inc(s[fq],s[fp]);
      end else
        begin
        f[fq]:=fp;
        inc(c[fp],c[fq]);
        inc(s[fp],s[fq]);
      end;
    end;
    
    Procedure move(p,q:longint);inline;
    var
     fp,fq:longint;
      begin
      fp:=find(pos[p]);
      fq:=find(pos[q]);
      if fp=fq then exit;
      dec(c[fp]);
      dec(s[fp],p);
      inc(c[fq]);
      inc(s[fq],p);
      inc(top);
      pos[p]:=top;
      f[pos[p]]:=fq;
    end;
    
      begin
      while not eof do
        begin
        readln(n,m);top:=n;
        for i:=1 to n do begin f[i]:=i;c[i]:=1;pos[i]:=i;s[i]:=i; end;
        while m>0 do
          begin
          dec(m);
          read(op);
          case op of
            1:begin
              readln(p,q);
              union(p,q);
            end;
            2:begin
              readln(p,q);
              move(p,q);
            end;
            3:begin
              readln(p);
              writeln(c[find(pos[p])],' ',s[find(pos[p])]);
            end;
          end;
        end;
      end;
    
    end.
    
  • 相关阅读:
    第三次上机作业
    第二次实训作业
    java第二次作业
    java程序设计第一次作业
    实训作业1
    java2
    我的第一次java作业
    第六次实训作业异常处理
    事件处理程序
    实训作业4
  • 原文地址:https://www.cnblogs.com/htfy/p/3063565.html
Copyright © 2011-2022 走看看