#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N = 1005, M = 2e4 + 5, INF = 1e9;
int head[N], ver[M], c[M], net[M], f[M]; int tot, pre[N], q[N], n, m, S, T, vis[N]; void add(int a, int b, int w) { ver[tot] = b, c[tot] = w, net[tot] = head[a], head[a] = tot++; }
bool bfs() { int front = 0, tail = -1; memset(vis, false, sizeof(vis)); vis[S] = true, f[S] = INF, q[++tail] = S; while (front <= tail) { int u = q[front++]; for (int i = head[u]; i; i = net[i]) { int v = ver[i]; if (!vis[v] && c[i]) { vis[v] = true; f[v] = min(f[u], c[i]); pre[v] = i; if (v == T) return true; q[++tail] = v; } } } return false; }
long long EK() { long long res = 0; while (bfs()) { res += f[T]; for (int i = T; i != S; i = ver[pre[i] ^ 1]) c[pre[i]] -= f[T], c[pre[i] ^ 1] += f[T]; } return res; }
int main() { scanf("%d%d%d%d", &n, &m, &S, &T); while (m--) { int u, v, w; scanf("%d%d%d", &u, &v, &w); add(u, v, w), add(v, u, 0); } printf("%lld", EK()); return 0; }
dinic求最大流O(n2m)
主要是对EK算法进行了一些优化
#include<iostream> #include<cstring> #include<cstdio> using namespace std; const int N = 1e4 + 5, M = 2e5 + 5, INF = 1e9;
int n, m, S, T; int head[N], net[M], cpt[M], ver[M],idx; int f[N], cur[N], d[N], q[N];
void add(int a, int b, int c) { net[idx] = head[a]; ver[idx] = b; cpt[idx] = c; head[a] = idx++; }
bool bfs() { int front = 0, tail = 0; memset(d, -1, sizeof(d)); q[0] = S, d[S] = 0, cur[S] = head[S]; while (front <= tail) { int u = q[front++]; for (int i = head[u]; ~i; i = net[i]) { int v = ver[i]; if (d[v] == -1 && cpt[i]) { d[v] = d[u] + 1; f[v] = min(f[u], cpt[i]); cur[v] = head[v]; if (v == T) return true; q[++tail] = v; } } } return false; }
int find(int u, int limit) { if (u == T) return limit; int flow = 0; for (int i = cur[u]; ~i && flow < limit; i = net[i]) { cur[u] = i; int v = ver[i]; if (d[v] == d[u] + 1 && cpt[i]) { int x = find(v, min(limit - flow, cpt[i])); if (!x) d[v] = -1; cpt[i] -= x, cpt[i ^ 1] += x, flow += x; } } return flow; }
int dinic() { int res = 0, flow; while (bfs()) { while (flow = find(S, INF)) res += flow; } return res; }
int main() { scanf("%d%d%d%d", &n, &m, &S, &T); memset(head, -1, sizeof(head)); while (m--) { int u, v, w; scanf("%d%d%d", &u, &v, &w); add(u, v, w), add(v, u, 0); } printf("%d", dinic()); return 0; }
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N = 105, M = 5205, INF = 1e8;
int n, m, S, T; int head[N], ver[M], net[M], cpt[M], idx; int q[N], cur[N], d[N], f[N], front, tail;
void add(int a, int b , int c) { net[idx] = head[a], ver[idx] = b, cpt[idx] = c, head[a] = idx++; }
bool bfs() { front = 0, tail = 0; memset(d, -1, sizeof(d)); q[0] = S, d[S] = 0, cur[S] = head[S]; while (front <= tail) { int u = q[front++]; for (int i = head[u]; ~i; i = net[i]) { int v = ver[i]; if (d[v] == -1 && cpt[i]) { d[v] = d[u] + 1; cur[v] = head[v]; if (v == T) return true; q[++tail] = v; } } } return false; }
int find(int u, int limit) { if (u == T) return limit; int flow = 0; for (int i = cur[u]; ~i && flow < limit; i = net[i]) { cur[u] = i; int v = ver[i]; if (d[v] == d[u] + 1 && cpt[i]) { int x = find(v, min(limit - flow, cpt[i])); if (!x) d[v] = -1; cpt[i] -= x, cpt[i ^ 1] += x, flow += x; } } return flow; }
int dinic() { int res = 0, flow; while (bfs()) { while (flow = find(S, INF)) res += flow; } return res; }
int main() { int m, n; scanf("%d%d", &m, &n); memset(head, -1, sizeof(head)); S = 0, T = n + 1; for (int i = 1; i <= m; i++) add(S, i , 1), add(i, S ,0); for (int i = m + 1; i <= n; i++) add(i, T, 1), add(T, i, 0); int u, v; while (scanf("%d %d", &u, &v) && ~u && ~v) { add(u, v, 1), add(v, u, 0); } printf("%d\n", dinic()); for (int i = 0; i < idx; i += 2) if (!cpt[i] && ver[i] > m && ver[i] <= n) printf("%d %d\n", ver[i ^ 1], ver[i]); return 0; }
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N = 505, M = 2e5 + 5, INF = 1e8;
int n, m, S, T; int head[N], ver[M], net[M], cpt[M], idx; int q[N], cur[N], d[N], R[N], C[N], ans[N][N];
void add(int a, int b, int c) { net[idx] = head[a], ver[idx] = b, cpt[idx] = c, head[a] = idx++; net[idx] = head[b], ver[idx] = a, cpt[idx] = 0, head[b] = idx++; }
bool bfs() { int front = 0, tail = 0; memset(d, -1, sizeof(d)); q[0] = S, d[S] = 0, cur[S] = head[S]; while (front <= tail) { int u = q[front++]; for (int i = head[u]; ~i; i = net[i]) { int v = ver[i]; if (d[v] == -1 && cpt[i]) { d[v] = d[u] + 1; cur[v] = head[v]; if (v == T) return true; q[++tail] = v; } } } return false; }
int find(int u, int limit) { if (u == T) return limit; int flow = 0; for (int i = cur[u]; ~i && flow < limit; i = net[i]) { cur[u] = i; int v = ver[i]; if (d[v] == d[u] + 1 && cpt[i]) { int x = find(v, min(limit - flow, cpt[i])); if (!x) d[v] = -1; cpt[i] -= x, cpt[i ^ 1] += x, flow += x; } } return flow; }
int dinic() { int res = 0, flow; while (bfs()) { while (flow = find(S, INF)) res += flow; } return res; }
int main() { int flux = 0; scanf("%d%d", &m, &n); memset(head, -1, sizeof(head)); S = 0, T = n + m + 1; for (int i = 1; i <= m; i++) { scanf("%d", &R[i]); add(S, i, R[i]), flux += R[i]; } for (int i = m + 1; i <= m + n; i++) { scanf("%d", &C[i]); add(i, T, C[i]); for (int j = 1; j <= m; j++) add(j, i, 1); } if (dinic() == flux) printf("1\n"); else { printf("0"); return 0; } for (int i = 0; i < idx; i += 2) { if (cpt[i ^ 1] && ver[i] > m && ver[i] <= m + n) ans[ver[i ^ 1]][++ans[ver[i ^ 1]][0]] = ver[i] - m; } for (int i = 1; i <= m; i++) { for (int j = 1; j <= ans[i][0]; j++) printf("%d ", ans[i][j]); printf("\n"); } return 0; }
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N = 205, M = 20405, INF = 1e8;
int n, m, S, T; int head[N], ver[M], net[M], cpt[M], idx; int q[N], cur[N], d[N], cm[M], in[N], out[N];
void add(int a, int b, int up, int low) { net[idx] = head[a], ver[idx] = b, cpt[idx] = up - low, cm[idx] = low, head[a] = idx++; net[idx] = head[b], ver[idx] = a, cpt[idx] = 0, cm[idx] = low, head[b] = idx++; }
bool bfs() { int front = 0, tail = 0; memset(d, -1, sizeof(d)); q[0] = S, d[S] = 0, cur[S] = head[S]; while (front <= tail) { int u = q[front++]; for (int i = head[u]; ~i; i = net[i]) { int v = ver[i]; if (d[v] == - 1 && cpt[i]) { d[v] = d[u] + 1; cur[v] = head[v]; if (v == T) return true; q[++tail] = v; } } } return false; }
int find(int u, int limit) { if (u == T) return limit; int flow = 0; for (int i = cur[u]; ~i && flow < limit; i = net[i]) { cur[u] = i; int v = ver[i]; if (d[v] == d[u] + 1 && cpt[i]) { int x = find(v, min(limit - flow, cpt[i])); if (!x) d[v] = -1; cpt[i] -= x, cpt[i ^ 1] += x, flow += x; } } return flow; }
int dinic() { int res = 0, flow; while (bfs()) { while (flow = find(S, INF)) res += flow; } return res; }
int main() { int flux = 0; scanf("%d%d", &n, &m); memset(head, -1, sizeof(head)); S = 0, T = n + 1; for (int i = 1; i <= m; i++) { int u, v, Max, Min; scanf("%d%d%d%d", &u, &v, &Min, &Max); add(u, v, Max, Min); in[v] += Min, out[u] += Min; } for (int i = 1; i <= n; i++) { // cout << in[i] - out[i] << endl; if (in[i] - out[i] > 0) add(S, i, in[i] - out[i], 0), flux += in[i] - out[i]; else add(i, T, out[i] - in[i], 0); } if (flux == dinic()) { printf("YES\n"); for (int i = 0; i < (m << 1); i += 2) printf("%d\n", cpt[i ^ 1] + cm[i]); } else printf("NO"); return 0; }