P4843 清理雪道
作者:互联网
上下界网络流最小流
#include <iostream> #include <string> #include <cstring> #include <algorithm> #include <queue> #define FT(a, b) memset(a, b, sizeof(a)) #define FAT(a) memset(a, 0, sizeof(a)) using namespace std; const int N = 50003 + 10, M = (125003+ N) * 2; const int INF = 0x3f3f3f3f; int n, m, s, t, S, T; int h[N], ne[M], e[M], idx, w[M]; int deepth[N], cur[N], all[N], gap[N]; void add(int a, int b, int c) { e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++; swap(a, b), c = 0; e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++; } void bfs() { FT(deepth, -1); FAT(gap); queue<int> q; q.push(t); deepth[t] = 0; gap[0] = 1; while (q.size()) { int a = q.front(); q.pop(); for (int i = h[a]; ~i; i = ne[i]) { int j = e[i]; if (deepth[j] == -1) { deepth[j] = deepth[a] + 1; gap[deepth[j]]++; q.push(j); } } } } // int ans; int dfs(int now, int flow) { if (now == t) { // ans += flow; return flow; } int nowflow = 0; for (int i = cur[now]; ~i; i = ne[i]) { cur[now] = i; int j = e[i]; if (w[i] && deepth[j] + 1 == deepth[now]) { int k = dfs(j, min(flow - nowflow, w[i])); w[i] -= k, w[i ^ 1] += k, nowflow += k; if (nowflow == flow) return nowflow; } } --gap[deepth[now]]; if (!gap[deepth[now]]) gap[s] = n + 2; ++deepth[now]; ++gap[deepth[now]]; return nowflow; } int ISAP() { int ans = 0; bfs(); while (gap[s] < n) { memcpy(cur, h, sizeof(cur)); ans += dfs(s, INF); } return ans; } int main() { #ifdef ONLINE_JUDGE #else freopen("/home/wjy/code/in.txt", "r", stdin); // freopen("/home/wjy/code/ans1.txt","w", stdout); #endif ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); FT(h, -1), idx = 0; FAT(all); cin >> n; S = 0, T = ++n; s = n + 1, t = n + 2; for (int i = 1; i <= n; i++) { cin >> m; add(S, i, INF), add(i, T, INF); while (m > 0) { m--; int x; cin >> x; add(i, x, INF - 1); all[i] -= 1, all[x] += 1; } } for (int i = 1; i <= n; i++) { // cout << i << " " << all[i] << endl; if (all[i] > 0) add(s, i, all[i]); else add(i, t, -all[i]); } // ISAP(); add(T, S, INF); // cout << ISAP() << endl; ISAP(); int flow = w[idx - 1]; // cout << flow << endl; w[idx - 1] = w[idx - 2] = 0; s = T, t = S; cout << flow - ISAP() << endl; return 0; }
标签:now,idx,int,清理,P4843,雪道,deepth,add,gap 来源: https://www.cnblogs.com/ignorance/p/14091457.html