虽然算法还没有理解透,但以及迫不及待地想要A道题了。
非常裸的最大流,试试lrj的模板练练手。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std; const int maxn = + ;
const int INF = ; struct Edge
{
int from, to, cap, flow;
Edge(int u, int v, int c, int f):from(u), to(v), cap(c), flow(f) {}
}; int n, m, M;
vector<Edge> edges;
vector<int> G[maxn];
int a[maxn]; //到起点i的可改进量
int p[maxn]; //最短路数上p的入弧编号 void Init(int n)
{
for(int i = ; i < n; ++i) G[i].clear();
edges.clear();
} void AddEdge(int from, int to, int cap)
{
edges.push_back(Edge(from, to, cap, ));
edges.push_back(Edge(to, from, , )); //反向弧
m = edges.size();
G[from].push_back(m-);
G[to].push_back(m-);
} int MaxFlow(int s, int t)
{
int flow = ;
for(;;)
{
memset(a, , sizeof(a));
queue<int> Q;
Q.push(s);
a[s] = INF;
while(!Q.empty())
{
int x = Q.front(); Q.pop();
for(int i = ; i < G[x].size(); ++i)
{
Edge& e = edges[G[x][i]];
if(!a[e.to] && e.cap > e.flow)
{
p[e.to] = G[x][i];
a[e.to] = min(a[x], e.cap-e.flow);
Q.push(e.to);
}
}
if(a[t]) break;
}
if(!a[t]) break;
for(int u = t; u != s; u = edges[p[u]].from)
{
edges[p[u]].flow += a[t];
edges[p[u]^].flow -= a[t];
}
flow += a[t];
}
return flow;
} int main()
{
freopen("in.txt", "r", stdin); while(scanf("%d%d", &M, &n) == )
{
Init(n);
int u, v, c;
for(int i = ; i < M; ++i)
{
scanf("%d%d%d", &u, &v, &c);
AddEdge(u-, v-, c);
}
printf("%d\n", MaxFlow(, n-));
} return ;
}
代码君