vijosP1524网络流最小割

由于yxy小朋友做了一些不该做的事,他被jzp关进了一个迷宫里。由于jzp最近比较忙,疏忽大意了一些,yxy可以在迷宫中任意走动。整个迷宫可以被看作是一个无向图。迷宫中有一些结点有传送点,可以让他逃离这个迷宫。jzp发明了一种机器人,可以监视迷宫中的道路,被监视的道路yxy不能通过,我们简单的认为监视一条道路的代价即为这条道路的长度。现在jzp正在忙,请你编一个程序算出使yxy无法逃离迷宫的最小监控总代价。(yxy一开始在1号结点)

输入格式

第1行:两个自然数n和e,分别表示迷宫的节点数和边数。

第2至e+1行:每行三个自然数a、b和w,表示a和b之间有一条道路,长度为w。

第e+2行:一个自然数m,表示有传送点结点的个数。

第e+3行:m个自然数,表示有传送点的结点。

输出格式

一个自然数,表示最小监视总代价。

</pre><pre name="code" class="delphi">
program wangluoliu;
var ans,f,i,j,n,e,a1,b1,w,m,top,tail,u,v,t,c:longint;
    cap,flow:array[1..101,1..101]of longint;
    a,p:array[1..101]of longint;
    b:array[1..100001]of longint;
function min(a,b:longint):longint;
begin
 if a<b then min:=a else min:=b;
end;
begin
 read(n,e);
 for i:=1 to n do
  for j:=1 to n do cap[i,j]:=-1;
 for i:=1 to e do
  begin
   read(a1,b1,w);
   cap[a1,b1]:=w;
   cap[b1,a1]:=w;
  end;
 read(m);
 for i:=1 to m do
  begin
   read(c);
   cap[c,n+1]:=maxlongint;
   cap[n+1,c]:=maxlongint;//超级汇点
  end;
//最大流最小割算法
 f:=0;t:=n+1;
 fillchar(flow,sizeof(flow),0);
 while true do
  begin
   fillchar(a,sizeof(a),0);
   a[1]:=maxlongint;
   top:=1;tail:=1;
   b[top]:=1;//s
   repeat
    u:=b[top];
    for v:=1 to n+1 do
     if (a[v]=0)and(cap[u,v]>flow[u,v]) then
      begin
       p[v]:=u;
       tail:=tail+1;
       b[tail]:=v;
       a[v]:=min(a[u],cap[u,v]-flow[u,v]);
      end;
    top:=top+1;
   until top>tail;
   if a[t]=0 then break;
   u:=t;
   while u<>1 do
    begin
     flow[p[u],u]:=flow[p[u],u]+a[t];
     flow[u,p[u]]:=flow[u,p[u]]-a[t];
     u:=p[u];
    end;
   f:=f+a[t];
  end;
 for i:=1 to n+1 do
  if a[i]>0 then
   for j:=1 to n+1 do
    if (cap[i,j]>0)and(a[j]=0) then ans:=ans+cap[i,j];
 writeln(ans);
end.


你可能感兴趣的:(最小割,网络流)