题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5889
BFS一边找最短路一边增广,如果走到终点的时候走过的距离是最短路,那么就增广这条路径,否则终止增广。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <vector>
#define maxn 1100
#define INF 100000000
using namespace std;
struct Edge
{
int from,to,cap,flow;
Edge(int u,int v,int c,int f):
from(u),to(v),cap(c),flow(f) {}
};
struct Dinic
{
int n,m,s,t;
vector<Edge> edges;
vector<int> G[maxn];
bool vis[maxn];
int d[maxn];
int cur[maxn];
int p[maxn];
int a[maxn];
bool first;
int minLen;
void init(int n)
{
for (int i=0; i<n; i++)
G[i].clear();
edges.clear();
}
void Addedge(int from,int to,int cap)
{
edges.push_back(Edge(from,to,cap,0));
edges.push_back(Edge(to,from,0,0));
m = edges.size();
G[from].push_back(m-2);
G[to].push_back(m-1);
}
bool bfs(long long& flow)
{
memset(vis,false,sizeof(vis));
queue<int> Q;
Q.push(s);
d[s] = 0;
vis[s] = true;
a[s] = INF;
bool flag = false;
while (!Q.empty())
{
int x = Q.front();
Q.pop();
for (int i=0; i<G[x].size(); i++)
{
Edge& e = edges[G[x][i]];
if (!vis[e.to] && e.cap>e.flow)
{
vis[e.to] = true;
d[e.to] = d[x]+1;
p[e.to] = G[x][i];
a[e.to] = min(a[x],e.cap-e.flow);
Q.push(e.to);
if (e.to == n)
{
if (first)
{
first = false;
flag = true;
minLen = d[e.to];
}
else if (d[e.to] == minLen)
{
flag = true;
}
break;
}
}
}
if (flag)
break;
}
if (!flag) return false;
for (int u=t; u!=s; u=edges[p[u]].from)
{
edges[p[u]].flow += a[t];
edges[p[u]^1].flow -= a[t];
}
flow += a[t];
return true;
}
int Maxflow(int s,int t)
{
this->s = s;
this->t = t;
long long flow = 0;
while (bfs(flow));
return flow;
}
};
int main()
{
int t;
Dinic a;
scanf("%d",&t);
while (t > 0)
{
t--;
int m;
scanf("%d%d",&a.n,&m);
a.init(a.n);
for (int i=0; i<m; i++)
{
int u, v, w;
scanf("%d%d%d",&u,&v,&w);
a.Addedge(u,v,w);
a.Addedge(v,u,w);
}
long long ans;
a.first = true;
printf("%d\n",a.Maxflow(1,a.n));
}
return 0;
}