题解:最大流问题,采用ISAP算法
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int INF = 2e9;
const int MAXN = 1e5 + 10;
struct Edge {
int to, next, cap;
} e[MAXN << 2];
int tot, head[MAXN], cur[MAXN];
int num[MAXN], dep[MAXN];
void Init() {
tot = 0;
memset(head, -1, sizeof(head));
}
void add(int u, int v, int c) {
e[tot].to = v;
e[tot].cap = c;
e[tot].next = head[u];
head[u] = tot++;
}
void BFS(int start, int end) {
memset(dep, -1, sizeof(dep));
memset(num, 0, sizeof(num));
dep[end] = 0;
num[0]++;
queue<int> q;
q.push(end);
while(!q.empty()) {
int u = q.front(); q.pop();
for(int i = head[u];i != -1;i = e[i].next) {
int v = e[i].to;
if(dep[v] != -1) continue;
dep[v] = dep[u] + 1;
num[dep[v]]++;
q.push(v);
}
}
}
int S[MAXN<<2];
int ISAP(int start, int end, int N) {
BFS(start, end);
int u = start;
int top = 0;
int ans = 0;
while(dep[start] < N) {
if(u == end) {
int Min = INF;
int inser;
for(int i = 0;i < top;i++) {
if(Min > e[S[i]].cap) {
Min = e[S[i]].cap;
inser = i;
}
}
for(int i = 0;i < top;i++) {
e[S[i]].cap -= Min;
e[S[i]^1].cap += Min;
}
ans += Min;
top = inser;
u = e[S[top]^1].to;
continue;
}
bool flag = false;
int v;
int temp = -1;
for(int i = head[u];i!=-1;i = e[i].next) {
v = e[i].to;
if(e[i].cap > 0 && dep[v]+1==dep[u]) {
flag = true;
temp = i;
break;
}
}
if(flag) {
S[top++] = temp;
u = v;
continue;
}
int Min = N;
for(int i = head[u]; i != -1;i = e[i].next) {
if(e[i].cap && dep[e[i].to] < Min) {
Min = dep[e[i].to];
}
}
if((--num[dep[u]] == 0)) break;
num[dep[u] = Min+1]++;
if(u!=start) u=e[S[--top]^1].to;
}
return ans;
}
int main() {
int T;
int n,m;
scanf("%d", &T);
while(T--) {
scanf("%d%d", &n, &m);
int start, end, le = INF, ri = -INF;
for(int i = 1;i <= n;i++) {
int x,y;
scanf("%d%d", &x, &y);
if(x < le) {le = x; start = i;}
if(x > ri) {ri = x; end = i;}
}
Init();
for(int i = 1; i <= m;i++) {
int u, v, c;
scanf("%d%d%d", &u, &v, &c);
add(u, v, c);
add(v, u, 0);
add(v,u,c);
add(u,v,0);
}
printf("%d\n", ISAP(start, end, n));
}
return 0;
}