zoukankan      html  css  js  c++  java
  • zoj_2587_Unique Attack

    题意:给定一个无向图,要求判定分离两个点的最小割是否唯一。

    解法:在求出最大流的基础上,从源点进行一次搜索,搜索按照未饱和的边进行,得到顶点子集S的顶点个数;再从汇点反向搜索未饱和的边,得到子集T的顶点个数,判定顶点数相加是否等于总共的顶点数。

    代码:

    type
      arr=record
            y,w,next:longint;
          end;
    var
      n,m,st,ed,nm,vs,vt,ans:longint;
      a:array [0..200001] of arr;
      ls,dis,q:array [0..1001] of longint;
      v:array [0..1001] of boolean;
    procedure add(x,y,w:longint);
    begin
      inc(nm);
      a[nm].y:=y; a[nm].w:=w;
      a[nm].next:=ls[x]; ls[x]:=nm;
    end;
    
    function min(o,p:longint):longint;
    begin
      if o<p then exit(o);
      exit(p);
    end;
    
    function bfs:boolean;
    var
      head,tail,xx,i:longint;
    begin
      fillchar(v,sizeof(v),false);
      tail:=1; head:=0; dis[vt]:=1;
      v[vt]:=true; q[1]:=1;
      while head<tail do
        begin
          inc(head); xx:=q[head];
          i:=ls[xx];
          while i<>-1 do
            with a[i] do
              begin
                if (not v[y]) and (w>0) then
                  begin
                    v[y]:=true;
                    dis[y]:=dis[xx]+1;
                    if y=vt then exit(true);
                    inc(tail);
                    q[tail]:=y;
                  end;
                i:=next;
              end;
        end;
      exit(false);
    end;
    
    function addflow(x,maxflow:longint):longint;
    var
      i,o:longint;
    begin
      if (x=vt) then exit(maxflow);
      addflow:=0; i:=ls[x];
      while i<>-1 do
        with a[i] do
          begin
            if (dis[y]=dis[x]+1) and (w>0) then
              begin
                o:=addflow(y,min(maxflow-addflow,w));
                if o>0 then
                  begin
                    inc(addflow,o);
                    dec(a[i].w,o);
                    inc(a[i xor 1].w,o);
                    if addflow=maxflow then exit(maxflow);
                  end;
              end;
            i:=next;
          end;
      if addflow=0 then dis[x]:=-1;
    end;
    
    procedure init;
    var
      i,x,y,w:longint;
    begin
      fillchar(ls,sizeof(ls),255);
      readln(n,m,st,ed); nm:=0;
      vs:=886; vt:=888;
      add(vs,st,maxlongint); add(st,vs,0);
      add(ed,vt,maxlongint); add(vt,ed,0);
      for i:=1 to m do
        begin
          readln(x,y,w);
          add(x,y,w); add(y,x,w);
        end;
    end;
    
    procedure getflow;
    begin
      ans:=0;
      while bfs do
        ans:=ans+addflow(vs,maxlongint);
    end;
    
    procedure find_l(x:longint; var num:longint);
    var
      i:longint;
    begin
      i:=ls[x];
      while i<>-1 do
        begin
          if (a[i xor 1].w>0) and (not v[a[i].y]) then
            begin
              inc(num);
              v[a[i].y]:=true;
              find_l(a[i].y,num);
            end;
          i:=a[i].next;
        end;
    end;
    
    procedure find_r(x:longint; var num:longint);
    var
      i:longint;
    begin
      i:=ls[x];
      while i<>-1 do
        begin
          if (a[i xor 1].w>0) and (not v[a[i].y]) then
            begin
              inc(num);
              v[a[i].y]:=true;
              find_r(a[i].y,num);
            end;
          i:=a[i].next;
        end;
    end;
    
    procedure print;
    var
      anum,bnum:longint;
    begin
      anum:=0; bnum:=0;
      fillchar(v,sizeof(v),false);
      v[vs]:=true; v[vt]:=true;
      find_l(vs,anum);
      fillchar(v,sizeof(v),false);
      v[vs]:=true; v[vt]:=true;
      find_r(vt,bnum);
      if anum+bnum=n then writeln('UNIQUE')
                     else writeln('AMBIGUOUS');
    end;
    
    begin
      init;
      getflow;
      print;
    end.
    

    上面代码是假的。

  • 相关阅读:
    Discuz论坛自动发帖机
    C#测试数据库连接是否成功
    JS重写提示框(confirm)
    随笔 选择
    随笔 诚实
    web项目经理手册【1】版本控制流程
    Asp.net多层架构中的变量引用与传递
    ASP.NET跨页面传值技巧总结
    web项目经理手册【3】Code Review
    web项目经理手册【7】项目经理需要铭记在心的话
  • 原文地址:https://www.cnblogs.com/zyx-crying/p/9319504.html
Copyright © 2011-2022 走看看