网络流的空间要好好算!!!
不然就各种出事。。。
没有账号,懂个思路就好了
看起来是前面那题多了个二分,待会去敲一敲
感觉自己最小割怎么跟没学过一样,摘了个oi-wiki上的模型
乍一看怎么和太空飞行计划一模一样
确实是一样的233
但怎么我之前会现在就连这个都不会了,药丸药丸
自闭了
#include <bits/stdc++.h> using namespace std; const int N = 30010, M = 280010; int n, m, a[110][110], s[110][110], sa[110][110], ss[110][110], id[110][110], tot, sum; int head[N], to[M], nxt[M], edge[M], cnt = 1, st, ed, h[N]; void add_edge(int u, int v, int w) { to[++cnt] = v, edge[cnt] = w, nxt[cnt] = head[u], head[u] = cnt; } void addedge(int u, int v, int w) { add_edge(u, v, w), add_edge(v, u, 0); } queue<int> q; int d[N]; bool bfs() { while (q.size()) q.pop(); for (int i = 0; i <= ed; i++) d[i] = 0, h[i] = head[i]; q.push(st), d[st] = 1; while (q.size()) { int u = q.front(); q.pop(); for (int i = head[u]; i; i = nxt[i]) { int v = to[i]; if (edge[i] && !d[v]) { d[v] = d[u] + 1; if (v == ed) return true; q.push(v); } } } return false; } int dinic(int u, int flow) { if (u == ed) return flow; int rest = flow, now; for (int &i = h[u]; i; i = nxt[i]) { int v = to[i]; if (edge[i] && d[v] == d[u] + 1) { now = dinic(v, min(edge[i], rest)); //if (!now) d[v] = -1; edge[i] -= now, edge[i ^ 1] += now, rest -= now; } } return flow - rest; } int main() { cin >> n >> m; for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) scanf("%d", &a[i][j]), id[i][j] = ++tot, sum += a[i][j]; for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) scanf("%d", &s[i][j]), sum += s[i][j]; for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) scanf("%d", &sa[i][j]), sum += sa[i][j]; for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) scanf("%d", &ss[i][j]), sum += ss[i][j]; st = 0, ed = tot * 3 + 1; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { addedge(st, id[i][j], a[i][j]), addedge(id[i][j], ed, s[i][j]); int x = tot + id[i][j], y = x + tot; addedge(st, x, sa[i][j]), addedge(y, ed, ss[i][j]); addedge(x, id[i][j], 0x3f3f3f3f), addedge(id[i][j], y, 0x3f3f3f3f); if (i > 1) addedge(x, id[i - 1][j], 0x3f3f3f3f), addedge(id[i - 1][j], y, 0x3f3f3f3f); if (j > 1) addedge(x, id[i][j - 1], 0x3f3f3f3f), addedge(id[i][j - 1], y, 0x3f3f3f3f); if (i < n) addedge(x, id[i + 1][j], 0x3f3f3f3f), addedge(id[i + 1][j], y, 0x3f3f3f3f); if (j < m) addedge(x, id[i][j + 1], 0x3f3f3f3f), addedge(id[i][j + 1], y, 0x3f3f3f3f); } } int maxflow = 0, flow = 0; while (bfs()) while (flow = dinic(st, 0x3f3f3f3f)) maxflow += flow; cout << sum - maxflow << endl; return 0; }
#include <bits/stdc++.h> using namespace std; inline int read() { int out = 0; bool flag = false; register char cc = getchar(); while (cc < '0' || cc > '9') { if (cc == '-') flag = true; cc = getchar(); } while (cc >= '0' && cc <= '9') { out = (out << 3) + (out << 1) + (cc ^ 48); cc = getchar(); } return flag ? -out : out; } inline void write(int x, char ch) { if (x < 0) putchar('-'), x = -x; if (x == 0) putchar('0'); else { int num = 0; char cc[22]; while (x) cc[++num] = x % 10 + 48, x /= 10; while (num) putchar(cc[num--]); } putchar(ch); } const int N = 210, M = 42000; int n, m, s, t, inf[N], outf[N], dow[M]; int head[N], to[M], nxt[M], edge[M], cnt = 1, h[N]; void add_edge(int u, int v, int w) { to[++cnt] = v, edge[cnt] = w, nxt[cnt] = head[u], head[u] = cnt; } void addedge(int u, int v, int w) { add_edge(u, v, w), add_edge(v, u, 0); } queue<int> q; int d[N]; bool bfs() { while (q.size()) q.pop(); for (int i = 0; i <= t; i++) d[i] = 0, h[i] = head[i]; q.push(s), d[s] = 1; while (q.size()) { int u = q.front(); q.pop(); for (int i = head[u]; i; i = nxt[i]) { int v = to[i]; if (edge[i] && !d[v]) { d[v] = d[u] + 1; if (v == t) return true; q.push(v); } } } return false; } int dinic(int u, int flow) { if (u == t) return flow; int rest = flow, now; for (int &i = h[u]; i; i = nxt[i]) { int v = to[i]; if (edge[i] && d[v] == d[u] + 1) { now = dinic(v, min(rest, edge[i])); edge[i] -= now, edge[i ^ 1] += now, rest -= now; } } return flow - rest; } int main() { n = read(), m = read(); s = 0, t = n + 1; for (int i = 1; i <= m; i++) { int u = read(), v = read(), down = read(), up = read(); outf[u] += down, inf[v] += down, dow[i] = down, addedge(u, v, up - down); } int sum = 0; for (int i = 1; i <= n; i++) { if (inf[i] > outf[i]) addedge(s, i, inf[i] - outf[i]); if (inf[i] < outf[i]) addedge(i, t, outf[i] - inf[i]); } while (bfs()) dinic(s, 0x3f3f3f3f); bool flag = false; for (int i = head[s]; i; i = nxt[i]) if (!(i & 1)) flag |= (edge[i] != 0); if (flag) puts("NO"); else { puts("YES"); for (int i = 2; i <= (m << 1); i += 2) write(dow[i >> 1] + edge[i ^ 1], ' '); } return 0; }
#include <bits/stdc++.h> using namespace std; const int N = 310, M = 12000; int n, k, f[310], s, t, S, T, ans; int head[N], to[M], nxt[M], edge[M], cst[M], cnt = 1, h[N]; void add_edge(int u, int v, int w, int c) { to[++cnt] = v, edge[cnt] = w, cst[cnt] = c; nxt[cnt] = head[u], head[u] = cnt; } void addedge(int u, int v, int w, int c) { add_edge(u, v, w, c), add_edge(v, u, 0, -c); } queue<int> q; int dis[N]; bool vis[N]; bool spfa() { for (int i = 0; i <= T; i++) dis[i] = 0x3f3f3f3f, vis[i] = false, h[i] = head[i]; q.push(S), dis[S] = 0; while (q.size()) { int u = q.front(); q.pop(); vis[u] = false; for (int i = head[u]; i; i = nxt[i]) { int v = to[i]; if (edge[i] && dis[v] > dis[u] + cst[i]) { dis[v] = dis[u] + cst[i]; if (!vis[v]) vis[v] = true, q.push(v); } } } return dis[T] != 0x3f3f3f3f; } int dinic(int u, int flow) { if (u == T) return flow; int rest = flow, now; vis[u] = true; for (int &i = h[u]; i; i = nxt[i]) { int v = to[i]; if (!vis[v] && edge[i] && dis[v] == dis[u] + cst[i]) { now = dinic(v, min(rest, edge[i])); edge[i] -= now, edge[i ^ 1] += now, rest -= now; ans += now * cst[i]; } } vis[u] = false; return flow - rest; } int main() { scanf("%d", &n); s = 1, t = n + 1, S = 0, T = n + 2; for (int u = 1; u <= n; u++) { scanf("%d", &k); for (int j = 1; j <= k; j++) { int v, c; scanf("%d%d", &v, &c); f[u]--, f[v]++, addedge(u, v, 0x3f3f3f3f, c), ans += c; } addedge(u, t, 0x3f3f3f3f, 0); } for (int i = 1; i <= n; i++) { if (f[i] > 0) addedge(S, i, f[i], 0); if (f[i] < 0) addedge(i, T, -f[i], 0); } addedge(t, s, 0x3f3f3f3f, 0); while (spfa()) dinic(S, 0x3f3f3f3f); cout << ans << endl; return 0; }
#include <bits/stdc++.h> using namespace std; int n, m, c[100010], u, pos[100010], dis[100010], fa[100010], ls[100010], rs[100010], ans; void dfs(int u) { if (u > n) return ; dfs(u << 1), dfs(u << 1 | 1); if (c[u]) dis[u] = 0, pos[u] = u; else dis[u] = 0x3f3f3f3f, pos[u] = -1; if ((u << 1) <= n && dis[u] > dis[u << 1] + 1) dis[u] = dis[u << 1] + 1, pos[u] = pos[u << 1]; if ((u << 1 | 1) <= n && dis[u] > dis[u << 1 | 1] + 1) dis[u] = dis[u << 1 | 1] + 1, pos[u] = pos[u << 1 | 1]; } int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) scanf("%d", &c[i]); dfs(1); for (int i = 1; i <= m; i++) { scanf("%d", &u); int now = u, s = 0, res = 0x3f3f3f3f, v = -1; while (now) { if (res > s + dis[now]) res = s + dis[now], v = now; if (fa[now] > 0) s -= 1; else s += 1; now >>= 1; } printf("%d ", ans += res); now = v, v = pos[v]; c[v]--; while (v != now) { int ff = v >> 1; if (v == (ff << 1)) { if (ls[ff] > 0) ls[ff]--; else fa[v]++; } else { if (rs[ff] > 0) rs[ff]--; else fa[v]++; } if (c[v]) dis[v] = 0, pos[v] = v; else dis[v] = 0x3f3f3f3f, pos[v] = -1; if ((v << 1) <= n && dis[v] > dis[v << 1] + (ls[v] ? -1 : 1)) dis[v] = dis[v << 1] + (ls[v] ? -1 : 1), pos[v] = pos[v << 1]; if ((v << 1 | 1) <= n && dis[v] > dis[v << 1 | 1] + (rs[v] ? -1 : 1)) dis[v] = dis[v << 1 | 1] + (rs[v] ? -1 : 1), pos[v] = pos[v << 1 | 1]; v = ff; } while (u != now) { if (fa[u]) fa[u]--; else { if (((u >> 1) << 1) == u) ls[u >> 1]++; else rs[u >> 1]++; } if (c[u]) dis[u] = 0, pos[u] = u; else dis[u] = 0x3f3f3f3f, pos[u] = -1; if ((u << 1) <= n && dis[u] > dis[u << 1] + (ls[u] ? -1 : 1)) dis[u] = dis[u << 1] + (ls[u] ? -1 : 1), pos[u] = pos[u << 1]; if ((u << 1 | 1) <= n && dis[u] > dis[u << 1 | 1] + (rs[u] ? -1 : 1)) dis[u] = dis[u << 1 | 1] + (rs[u] ? -1 : 1), pos[u] = pos[u << 1 | 1]; u >>= 1; } while (now) { if (c[now]) dis[now] = 0, pos[now] = now; else dis[now] = 0x3f3f3f3f, pos[now] = -1; if ((now << 1) <= n && dis[now] > dis[now << 1] + (ls[now] ? -1 : 1)) dis[now] = dis[now << 1] + (ls[now] ? -1 : 1), pos[now] = pos[now << 1]; if ((now << 1 | 1) <= n && dis[now] > dis[now << 1 | 1] + (rs[now] ? -1 : 1)) dis[now] = dis[now << 1 | 1] + (rs[now] ? -1 : 1), pos[now] = pos[now << 1 | 1]; now >>= 1; } } return 0; }