题意:给定一个无向图,要求判定分离两个点的最小割是否唯一。
解法:在求出最大流的基础上,从源点进行一次搜索,搜索按照未饱和的边进行,得到顶点子集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.
上面代码是假的。