2012 icpc 长春赛区的最大流模板题, 模板的高效性很重要
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#define MAXVERTEX 100001
#define MAXARC 400010
#define INF 0x7fffffff
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
struct Edge{
int v, val, next;
}edge[MAXARC];
int vertex, e_gap, head[MAXVERTEX];
int pre[MAXVERTEX], cur[MAXVERTEX], dis[MAXVERTEX], gap[MAXVERTEX];
void insert_arc(int u, int v, int w)
{
edge[e_gap].v = v; edge[e_gap].val = w;
edge[e_gap].next = head[u]; head[u] = e_gap ++;
swap(u, v);
edge[e_gap].v = v; edge[e_gap].val = 0;
edge[e_gap].next = head[u]; head[u] = e_gap ++;
}
void bfs(int source, int sink)
{
int u, v;
queue<int> q;
memset(dis, -1, sizeof(dis));
memset(gap, 0, sizeof(gap));
dis[sink] = 0;
gap[0] = 1; q.push(sink);
while( !q.empty() ) {
u = q.front(); q.pop();
for(int i = head[u]; -1 != i; i = edge[i].next) {
v = edge[i].v;
if( edge[i].val || -1 != dis[v] ) continue;
dis[v] = dis[u]+1; gap[ dis[v] ] ++;
q.push(v);
}
}
}
int i_sap(int source, int sink)
{
int u(source), v, min_dis, max_flow(0), path_flow(INF);
bfs(source, sink);
for(int i = 0; i <= vertex; i ++)
cur[i] = head[i];
gap[0] = vertex; pre[u] = u;
while( dis[source] < vertex ) {
loop:
for(int &i = cur[u]; -1 != i; i = edge[i].next) {
v = edge[i].v;
if( !edge[i].val || (dis[u] != dis[v]+1) ) continue;
pre[v] = u; path_flow = min(path_flow, edge[i].val);
u = v;
if( v == sink ) {
for(u = pre[u]; v != source; v = u, u = pre[u]) {
edge[cur[u]].val -= path_flow; edge[cur[u]^1].val += path_flow;
}
max_flow += path_flow; path_flow = INF;
}
goto loop;
}
min_dis = vertex;
for(int i = head[u]; -1 != i; i = edge[i].next) {
v = edge[i].v;
if( edge[i].val && min_dis > dis[v] ) {
cur[u] = i; min_dis = dis[v];
}
}
gap[ dis[u] ] --;
if( !gap[ dis[u] ] ) break;
dis[u] = min_dis+1;
gap[ dis[u] ] ++; u = pre[u];
}
return max_flow;
}
int main(int argc, char const *argv[])
{
//freopen("test.in", "r", stdin);
int cas, arc, source, sink, x, y, v, max_x, min_x;
scanf("%d", &cas);
while( cas-- ) {
scanf("%d %d", &vertex, &arc);
max_x = -INF; min_x = INF;
for(int i = 1; i <= vertex; i ++) {
scanf("%d %d", &x, &y);
if( min_x > x ) {
min_x = x; source = i;
}
if( max_x < x ) {
max_x = x; sink = i;
}
}
e_gap = 0;
memset(head, -1, sizeof(head));
for(int i = 0; i < arc; i ++) {
scanf("%d %d %d", &x, &y, &v);
insert_arc(x, y, v); insert_arc(y, x, v);
}
printf("%d\n", i_sap(source, sink));
}
return 0;
}