直接套用ISAP模板
我的模板不一定正确…… 不能参考!!!!!
/*
TASK:ditch
LANG:C++
*/
#include <iostream>
#include <queue>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
const int max_ver = 200 + 10;
int n, m;
struct edge
{
int ver, cap, flow;
edge *next, *rev;
edge(){}
edge(int _Ver, int _Cap, edge* _Next):ver(_Ver), cap(_Cap), next(_Next), flow(0), rev(NULL){}
}*net[max_ver]={NULL};
inline void insert_edge(int s, int t, int cap)
{
net[s] = new edge(t, cap, net[s]);
net[t] = new edge(s, 0, net[t]);
net[s] -> rev = net[t];
net[t] -> rev = net[s];
}
void init()
{
scanf("%d%d", &m, &n);
while (m--)
{
int a, b , c;
scanf("%d%d%d", &a, &b, &c);
insert_edge(a, b, c);
}
}
queue<int>q;
int dist[max_ver], numbs[max_ver];
void rev_bfs(int s = 1, int t = n)
{
q.push(t);
for (int i = 1; i <= n; ++ i) dist[i] = 0x7fffffff;
memset(numbs, 0, sizeof(numbs));
numbs[0] = 1;
q.push(t);
dist[t] = 0;
while (!q.empty())
{
int now = q.front();
q.pop();
for (edge *e = net[now]; e; e = e -> next)
{
int will = e -> ver;
if (dist[will] != 0x7fffffff || e -> rev -> cap == 0) continue;
dist[will] = dist[now] + 1;
++ numbs[dist[will]];
q.push(will);
}
}
}
edge *CurEdge[max_ver], *revpath[max_ver];
int totflow(0);
void augflow(int s = 1, int t = n)
{
int augflow = 0x7fffffff;
for (int i = s; i != t; i = CurEdge[i] -> ver)
{
//cout<<"["<<i<<"]"<<endl;
augflow = min(augflow, CurEdge[i] -> cap);
}
for (int i = s; i != t; i = CurEdge[i] -> ver)
{
CurEdge[i] -> cap -= augflow;
CurEdge[i] -> rev -> cap += augflow;
CurEdge[i] -> flow += augflow;
CurEdge[i] -> rev -> flow -= augflow;
}
totflow += augflow;
}
void maxflow(int s = 1, int t = n)
{
int totalflow = 0;
for (int i = 1; i <= n; ++ i) CurEdge[i] = net[i];//当前弧优化!
int now = s;
while (dist[s] < n) // 起点到终点的距离比n小。一旦到n,肯定是到不了。 比如1->2 如果1->2距离是2,肯定是不可能的
{
if (now == t)
{
augflow();
now = s;
}
edge *e;
for (e = CurEdge[now]; e; e = e -> next)
if (e -> cap > 0 && dist[now] == dist[e -> ver] + 1) break;//找到一个可行的路
if (e)
{
CurEdge[now] = e;
revpath[e -> ver] = e -> rev; //计算will是从哪里来的,为了回溯
now = e -> ver;
}else{ //失败了,显然要回溯
if (0 == (--numbs[dist[now]])) break; //如果一个距离已经没有了。 出现断层了 显然就应该结束了
CurEdge[now] = net[now];
int mindist = n;
for (edge *te = net[now]; te; te = te -> next)
if (te -> cap >0) mindist = min(mindist, dist[te -> ver]);
dist[now] = mindist + 1;
++ numbs[dist[now]];
if (now != s) now = revpath[now] -> ver;
}
}
printf("%d\n", totflow);
}
int main()
{
freopen("ditch.in","r",stdin);
freopen("ditch.out","w",stdout);
init();
rev_bfs(1, n);
maxflow(1, n);
return 0;
}