【BZOJ 1001】狼抓兔子(最大流)
阿新 • • 發佈:2019-01-27
ron define max \n 效率 cpp cstring inf tchar
題目鏈接
最大流裸題,沒什麽好說吧,恰好點數多,考驗網絡流的效率,正好練\(Dinic\)。
#include <cstdio> #include <queue> #include <cstring> #define INF 2147483647 using namespace std; const int MAXN = 1000010; const int MAXM = 8000010; inline int read(){ int s = 0, w = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') w = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * w; } struct Edge{ int next, to, rest; }e[MAXM]; int s, t, num = 1, n, m; int head[MAXN]; inline void Add(int from, int to, int flow){ e[++num] = (Edge){ head[from], to, flow }; head[from] = num; e[++num] = (Edge){ head[to], from, flow }; head[to] = num; } int level[MAXN], now, sum; queue <int> q; int re(){ memset(level, 0, sizeof level); while(q.size()) q.pop(); q.push(s); level[s] = 1; while(q.size()){ now = q.front(); q.pop(); for(int i = head[now]; i; i = e[i].next) if(e[i].rest && !level[e[i].to]){ level[e[i].to] = level[now] + 1; q.push(e[i].to); } } return level[t]; } int findflow(int u, int flow){ if(!flow || u == t) return flow; int f = 0, t; for(int i = head[u]; i; i = e[i].next){ if(e[i].rest && level[e[i].to] == level[u] + 1){ f += (t = findflow(e[i].to, min(flow - f, e[i].rest))); e[i].rest -= t; e[i ^ 1].rest += t; } } if(!f) level[u] = 0; return f; } int dinic(){ int ans = 0; while(re()) ans += findflow(s, INF); return ans; } inline int id(int i, int j){ return (i - 1) * m + j; } int main(){ n = read(); m = read(); s = id(1, 1); t = id(n, m); for(int i = 1; i <= n; ++i) for(int j = 1; j < m; ++j) Add(id(i, j), id(i, j + 1), read()); for(int i = 1; i < n; ++i) for(int j = 1; j <= m; ++j) Add(id(i, j), id(i + 1, j), read()); for(int i = 1; i < n; ++i) for(int j = 1; j < m; ++j) Add(id(i, j), id(i + 1, j + 1), read()); printf("%d\n", dinic()); return 0; }
【BZOJ 1001】狼抓兔子(最大流)