直接上最高效算法:DINIC
简单地说 Dinic Algorithm分为以下两步:
1)BFS:对原图进行分层:设当前节点为u,当前节点的层数值为Value(u),u的后继节点为{Sv},那么{Sv}中所有节点的层数值Value(v)均为Value(u)+1。
2)DFS:寻找增广路,修改残量网络直至找不到新的最大流。
插一个DINIC模板。
#include<bits/stdc++.h>
#define inf 2147483647
#define max_n 405
using namespace std;
int n,m,buf1,buf2,buf3,pos;
int head[max_n],depth[max_n],cur[max_n];
bool vis[max_n];
class Edge
{
public:
int from;int to;int con;int nxt;int flow;
}edge[4*max_n];
void addEdge(int x,int y,int z)
{
edge[pos].from=x;
edge[pos].to=y;
edge[pos].con=z;
edge[pos].nxt=head[x];
head[x]=pos++;
}
void dataIn()
{
for(int i=0;i<=402;i++)
edge[i].con=edge[i].flow=edge[i].to=edge[i].nxt=0;
memset(head,-1,sizeof head);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&buf1,&buf2,&buf3);
addEdge(buf1,buf2,buf3);
addEdge(buf2,buf1,0);
}
}
queue <int> q;
bool bfs()
{
memset(vis,0,sizeof(vis));
q.push(1); vis[1]=true; depth[1]=0;
int u,v;
while(!q.empty())
{
u=q.front();q.pop();
for(int i=head[u];i!=-1;i=edge[i].nxt)
{
v=edge[i].to;
if(!vis[v]&&edge[i].con>edge[i].flow)
{
vis[v]=true; depth[v]=depth[u]+1; q.push(v);
}
}
}
return vis[m];
}
int dfs(int u,int a)
{
if(u==m||!a) return a;
int flow=0,f;
for(int& i=cur[u];i!=-1;i=edge[i].nxt)
{
int v=edge[i].to;
if(depth[u]+1==depth[v]&&(f=dfs(v,min(edge[i].con-edge[i].flow,a))))
{
edge[i].flow+=f;
edge[i^1].flow-=f;
flow+=f;
a-=f;
if(!a) break;
}
}
return flow;
}
int main()
{
int ans=0;
dataIn();
while(bfs())
{
for(int i=1;i<=m;i++)
cur[i]=head[i];
ans+=dfs(1,inf);
cout<<ans;
}
printf("%d",ans);
return 0;
}