#include<stdio.h>
#include<string.h>
#include<iostream>
#include<queue>
#include<stack>
#include<vector>
#define M 300
#define Max 0xfffffff
using namespace std;
vector<int> map[M];
int G[M][M];
int d[M];//d[i]表示i结点所在的层数
int m,n;
bool v[M];
bool BFS(int S,int T)//用BFS进行分层
{
int i,p;
queue<int>que;
que.push(S);
memset(d,-1,sizeof(d));
d[S]=0;
while(!que.empty())
{
p=que.front();
que.pop();
for(i=0;i<map[p].size();i++)
{
int u=map[p][i];
if(G[p][u]>0&&d[u]==-1)
{
d[u]=d[p]+1;
if(u==T)
return true;
else que.push(u);
}
}
}
return false;
}
int Dinic(int S,int T)
{
int i,p;
int min;//路径中边的容量的最小值
int nMinc;//容量最小边的起点
int MaxFlow=0;//最大流
int stack[M];//栈
int top,base;
while(BFS(S,T))
{
top=0;base=0;
memset(v,false,sizeof(v));
stack[top++]=S;
v[S]=true;
while(top>base)
{
p=stack[top-1];
if(p==T)//p是汇点
{
min=Max;
for(i=1;i<top;i++)
{
int u,v;
u=stack[i-1];
v=stack[i];
if(min>G[u][v])
{
min=G[u][v];
nMinc=u;
}
}
//增广,改图
MaxFlow+=min;
for(i=1;i<top;i++)
{
int u,v;
u=stack[i-1];
v=stack[i];
G[u][v]-=min;//增广,改图
G[v][u]+=min;//添加反向边
}
while(top>base&&stack[top-1]!=nMinc)//退栈到 nMinC成为栈顶,以便继续dfs
{
top--;
}
}
else //p不是汇点
{
for(i=0;i<map[p].size();i++)
{
int u=map[p][i];
if(!v[u]&&d[u]==d[p]+1&&G[p][u]>0)//只往下一层的没有走过的节点走
{
v[u]=true;
stack[top++]=u;
break;
}
}
if(i>=map[p].size())//找不到下一个点
top--;//回溯
}
}
}
return MaxFlow;
}
int main()
{
int i;
while(scanf("%d%d",&m,&n)!=EOF)
{
memset(G,0,sizeof(G));
memset(map,0,sizeof(map));
for(i=0;i<m;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
G[a][b]+=c;//两点之间可能有多条边
map[a].push_back(b);
map[b].push_back(a);
}
printf("%d\n",Dinic(1,n));
}
}
Dinic 模板
最新推荐文章于 2019-08-09 15:40:14 发布