Dinic算法
网络流的经典算法,原理依旧遵循增广路定理,只是在Ford-Fulkson算法的基础上,每次增广前求出残量网络中每个点到源点的距离,确保每次流的都是最短路。
注意当前弧优化
//Dinic
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#define rep(i,x,y) for (int i=x;i<=y;i++)
#define dep(i,y,x) for (int i=y;i>=x;i--)
#define read(x) scanf("%d",&x)
using namespace std;
const int maxn=200+23,INF=(1<<23);
struct Edge{
int from,to,flow,cap;
Edge(int x1,int x2,int x3,int x4):from(x1),to(x2),flow(x3),cap(x4) {}
};
int d[maxn],cur[maxn],n,m,x,y,c,M,s,t;
bool vis[maxn];
vector<Edge> E;
vector<int> G[maxn];
void addedge(int u,int v,int c)
{
E.push_back(Edge(u,v,0,c));
E.push_back(Edge(v,u,0,0));
M=E.size();
G[u].push_back(M-2);
G[v].push_back(M-1);
}
bool BFS()
{
memset(vis,0,sizeof(vis));
queue<int> Q;
vis[s]=1;
Q.push(s);
d[s]=0;
while (!Q.empty())
{
int x=Q.front(),len=G[x].size();Q.pop();
rep(i,0,len-1)
{
Edge& Eg=E[G[x][i]];
if ((!vis[Eg.to]) && (Eg.cap>Eg.flow))
{
vis[Eg.to]=1;
Q.push(Eg.to);
d[Eg.to]=d[x]+1;
}
}
}
return vis[t];
}
int DFS(int k,int a)
{
if ((k==t) || (a==0)) return a;
int len=G[k].size(),flow=0,f;
for (int& i=cur[k];i<len;i++)
{
Edge& Ed=E[G[k][i]];
if ((d[k]+1)!=(d[Ed.to])) continue;
f=DFS(Ed.to,min(a,Ed.cap-Ed.flow));
if (f>0)
{
flow+=f;
Ed.flow+=f;
E[G[k][i]^1].flow-=f;
a-=f;
if (a==0) break;
}
}
return flow;
}
int Maxflow()
{
int flow=0;
while (BFS())
{
memset(cur,0,sizeof(cur));
flow+=DFS(s,INF);
}
return flow;
}
int main()
{
scanf("%d%d",&m,&n);
rep(i,1,m)
{
scanf("%d%d%d",&x,&y,&c);
addedge(x,y,c);
}
s=1;t=n;
printf("%d\n",Maxflow());
return 0;
}

浙公网安备 33010602011771号