[BZOJ 2006] 狼抓兔子
[题目链接]
https://www.lydsy.com/JudgeOnline/problem.php?id=1001
[算法]
最小割
[代码]
#include<bits/stdc++.h> using namespace std; #define MAXN 1010 const long long inf = 1e18; struct edge { int to; long long w; int nxt; } e[MAXN * MAXN * 8]; int i,j,n,m,tot,S,T,x; int head[MAXN * MAXN],depth[MAXN * MAXN]; long long ans,flow; template <typename T> inline void read(T &x) { long long f = 1; x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) { if (c == '-') f = -f; } for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0'; x *= f; } inline int getid(int x,int y) { return (x - 1) * m + y; } inline void addedge(int u,int v,long long w) { tot++; e[tot] = (edge){v,w,head[u]}; head[u] = tot; tot++; e[tot] = (edge){u,w,head[v]}; head[v] = tot; } inline bool bfs() { int i,u,v,w,l,r; static int q[MAXN * MAXN]; for (i = 1; i <= n * m; i++) depth[i] = 0; q[l = r = 1] = S; depth[S] = 1; while (l <= r) { u = q[l]; l++; for (i = head[u]; i; i = e[i].nxt) { v = e[i].to; w = e[i].w; if (!depth[v] && w) { depth[v] = depth[u] + 1; q[++r] = v; if (v == T) return true; } } } return false; } inline long long dinic(int u,long long flow) { int i,v; long long w,rest = flow,k; if (u == T) return flow; for (i = head[u]; i && rest; i = e[i].nxt) { v = e[i].to; w = e[i].w; if (depth[v] == depth[u] + 1 && w) { k = dinic(v,min(rest,w)); if (!k) depth[v] = 0; e[i].w -= k; e[i ^ 1].w += k; rest -= k; } } return flow - rest; } int main() { read(n); read(m); tot = 1; for (i = 1; i <= n; i++) { for (j = 1; j < m; j++) { read(x); addedge(getid(i,j),getid(i,j + 1),x); } } for (i = 1; i < n; i++) { for (j = 1; j <= m; j++) { read(x); addedge(getid(i,j),getid(i + 1,j),x); } } for (i = 1; i < n; i++) { for (j = 1; j < m; j++) { read(x); addedge(getid(i,j),getid(i + 1,j + 1),x); } } ans = 0; S = 1; T = n * m; while (bfs()) { while (flow = dinic(S,inf)) ans += flow; } printf("%lld\n",ans); return 0; }