(3)在同一次 DFS 中。如果从一个点引发不出任何的增广路径,就将这个点在层次图中抹去。
poj1273 链接:http://poj.org/problem?id=1273
Description
Input
Output
Sample Input
5 4 1 2 40 1 4 20 2 4 20 2 3 30 3 4 10
Sample Output
50
#include"stdio.h"
#include"string.h"
#define N 605
#define min(a,b) (a<b?a:b)
const int inf=0x7fffffff;
struct node
{
int u,v,w,next;
}map[N*4];
int cnt,n,m,s,t,head[N],q[N],dis[N];
void add(int u,int v,int w)
{
map[cnt].u=u;
map[cnt].v=v;
map[cnt].w=w;
map[cnt].next=head[u];
head[u]=cnt++;
map[cnt].u=v;
map[cnt].v=u;
map[cnt].w=0;
map[cnt].next=head[v];
head[v]=cnt++;
}
int bfs()
{
int i,x,v,t1,t2;
memset(dis,0,sizeof(dis)); //节点的高度标号
dis[s]=1;
t1=t2=0;
q[t2++]=s; //模拟队列
while(t1<t2)
{
x=q[t1++];
for(i=head[x];i!=-1;i=map[i].next)
{
v=map[i].v;
if(map[i].w&&!dis[v])
{
dis[v]=dis[x]+1;
if(v==n)
return 1;
q[t2++]=v;
}
}
}
return 0;
}
int dfs(int s,int lim)
{
int i,v,tmp,cost=0;
if(s==t)
return lim;
for(i=head[s];i!=-1;i=map[i].next) //枚举该点连通的所有边
{
v=map[i].v;
if(map[i].w&&dis[s]==dis[v]-1)
{
tmp=dfs(v,min(lim-cost,map[i].w));
if(tmp>0)
{
map[i].w-=tmp; //利用反向边的奇偶性,增加反向边的流量
map[i^1].w+=tmp;
cost+=tmp;
if(lim==cost)
break;
}
else //在同一次 DFS 中。如果从一个点引发不出任何的增广路径,就将这个点在层次图中抹去。
dis[v]=-1;
}
}
return cost;
}
int dinic()
{
int ans=0;
while(bfs())
ans+=dfs(s,inf);
return ans;
}
int main()
{
int u,v,w;
while(~scanf("%d%d",&m,&n))
{
cnt=0;
memset(head,-1,sizeof(head));
while(m--)
{
scanf("%d%d%d",&u,&v,&w);
add(u,v,w); //建边,反向边流量为零
}
s=1;t=n;
printf("%d\n",dinic());
}
return 0;
}
dinic算法学习(以poj1273为例),布布扣,bubuko.com
原文:http://blog.csdn.net/u011721440/article/details/38312759