Island Transport HDU 4280 Dinic模板
题目链接:https://cn.vjudge.net/contest/163017#problem/G
题目大意:给出N个点的坐标和M条有容量的边,找出从最西边的点到最东边的点的最大流量。
题目分析:抄的李东庆的模板,于是以后就打算用这个板子搞 Dinic 了。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100000 + 10;
const int INF = 0x3f3f3f3f;
struct node {
int to, w, next;
}Edge[maxn << 1];
int Head[maxn], cur[maxn], level[maxn], cnt;
void add(int u, int v, int w) {
Edge[cnt].to = v;
Edge[cnt].w = w;
Edge[cnt].next = Head[u];
Head[u] = cnt++;
Edge[cnt].to = u;
Edge[cnt].w = w; //反向边 题目是双向的 单向的话就是0
Edge[cnt].next = Head[v];
Head[v] = cnt++;
}
bool bfs(int s, int t) {
memset(level, -1, sizeof(level));
queue<int> q;
level[s] = 0;
q.push(s);
while(!q.empty()) {
int now = q.front();
q.pop();
for(int i = Head[now]; ~i; i = Edge[i].next) {
int to = Edge[i].to;
if(level[to] == -1 && Edge[i].w) {
level[to] = level[now] + 1;
q.push(to);
}
}
}
return level[t] != -1;
}
int dfs(int s, int t, int f) {
if(s == t) return f;
int flow = 0, d;
for(int &i = cur[s]; ~i; i = Edge[i].next) {
int to = Edge[i].to;
if(Edge[i].w && level[s] < level[to] && (d = dfs(to, t, min(f, Edge[i].w)))) {
f -= d;
Edge[i].w -= d;
Edge[i ^ 1].w += d;
flow += d;
if(!f) break;
}
}
if(!flow) level[s] = -1;
return flow;
}
int max_flow(int s, int e) {
int flow = 0;
while(bfs(s, e)) {
memcpy(cur, Head, sizeof(Head));
flow += dfs(s, e, INF);
}
return flow;
}
int main()
{
int t;
scanf("%d", &t);
while(t--) {
int n, m, s, e, sx = INF, ex = -INF;
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; i++) {
int x, y;
scanf("%d %d", &x, &y);
if(sx > x) {sx = x; s = i; }
if(ex < x) {ex = x; e = i; }
}
cnt = 0;
memset(Head, -1, sizeof(Head));
for(int i = 0; i < m; i++) {
int u, v, w;
scanf("%d %d %d", &u, &v, &w);
add(u, v, w);
}
int v = max_flow(s, e);
printf("%d\n", v);
}
}