题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1001
看到大佬们都是对偶图过的,写了个最大流水过去了QAQ,网络流的无向图直接建双向边(不用建0边),然后跑dinic,最基本的dinic会被卡,可以简单优化一下。
有空学了对偶图在补,(个_个)
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn = 6e6 + 10; 5 const int inf = INT_MAX; 6 struct node { 7 int e, w, next; 8 }edge[maxn]; 9 int head[maxn], len; 10 int d[maxn]; 11 void init() { 12 memset(head, -1, sizeof(head)); 13 len = 0; 14 } 15 void add(int s, int e, int w) { 16 edge[len].e = e; 17 edge[len].w = w; 18 edge[len].next = head[s]; 19 head[s] = len++; 20 } 21 inline int read() { 22 int x = 0, f = 1; char ch = getchar(); 23 while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); } 24 while (ch >= '0'&&ch <= '9') { x = x * 10 + ch - 48; ch = getchar(); } 25 return x * f; 26 } 27 bool bfs(int s, int e) { 28 queue<int>q; 29 memset(d, 0, sizeof(d)); 30 d[s] = 1; 31 q.push(s); 32 while (!q.empty()) { 33 int x = q.front(); q.pop(); 34 for (int i = head[x]; i != -1; i = edge[i].next) { 35 int y = edge[i].e; 36 if (edge[i].w && !d[y]) { 37 d[y] = d[x] + 1; 38 q.push(y); 39 } 40 } 41 } 42 return d[e]; 43 } 44 int dfs(int s, int e, int limit) { 45 if (s == e) 46 return limit; 47 int add, ans = 0; 48 for (int i = head[s]; i != -1; i = edge[i].next) { 49 int y = edge[i].e; 50 if (d[s] == d[y] - 1 && edge[i].w && (add = dfs(y, e, min(edge[i].w, limit)))) { 51 edge[i].w -= add; 52 edge[i ^ 1].w += add; 53 ans += add; 54 limit -= add; 55 if (!limit) 56 break; 57 } 58 } 59 if (ans) 60 return ans; 61 d[s] = -1; 62 return 0; 63 } 64 int dinic(int s, int e) { 65 int ans = 0, f; 66 while (bfs(s, e)) { 67 while (f = dfs(s, e, inf)) 68 ans += f; 69 } 70 return ans; 71 } 72 int main() { 73 int n, m, z; 74 n = read(), m = read(); 75 init(); 76 for (int i = 1; i <= n; i++) 77 for (int j = 1; j < m; j++) { 78 z = read(); 79 add(m*(i - 1) + j, m*(i - 1) + j + 1, z); 80 add(m*(i - 1) + j + 1, m*(i - 1) + j, z); 81 } 82 for (int i = 1; i < n; i++) 83 for (int j = 1; j <= m; j++) { 84 z = read(); 85 add(m*(i - 1) + j, m*i + j, z); 86 add(m*i + j, m*(i - 1) + j, z); 87 } 88 for (int i = 1; i < n; i++) 89 for (int j = 1; j < m; j++) { 90 z = read(); 91 add(m*(i - 1) + j, m*i + j + 1, z); 92 add(m*i + j + 1, m*(i - 1) + j, z); 93 } 94 printf("%d ", dinic(1, n*m)); 95 //system("pause"); 96 }