Problem UVALive - 3661 - Animal Run
Time Limit: 6000 mSec
Problem Description
Input
Output
Sample Input
3 4 5 6 4 4 3 1 7 5 3 5 6 7 8 8 7 6 5 5 5 5 6 6 6 0 0
Sample Output
Case 1: Minimum = 14
题解:一看就是最大流最小割,但是常规网络流的算法显然太慢了,这时候就引出了平面图最小割的概念,orz.
详见:https://wenku.baidu.com/view/a10e0529bd64783e09122ba9.html
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define REP(i, n) for (int i = 1; i <= (n); i++) 6 #define sqr(x) ((x) * (x)) 7 8 const int maxn = 6000000 + 100; 9 const int maxm = 12000000 + 100; 10 const int maxs = 10; 11 12 typedef long long LL; 13 typedef pair<int, int> pii; 14 typedef pair<double, double> pdd; 15 16 const LL unit = 1LL; 17 const int INF = 0x3f3f3f3f; 18 const LL Inf = 0x3f3f3f3f3f3f3f3f; 19 const double eps = 1e-14; 20 const double inf = 1e15; 21 const double pi = acos(-1.0); 22 const LL mod = 1000000007; 23 const int base = 10000; 24 25 struct Edge 26 { 27 LL to, next, w; 28 Edge(LL to = 0, LL next = 0, LL w = 0) : to(to), next(next), w(w) {} 29 } edge[maxm]; 30 31 struct HeapNode 32 { 33 LL u, dis; 34 bool operator<(const HeapNode &a) const 35 { 36 return dis > a.dis; 37 } 38 }; 39 40 LL head[maxn], tot; 41 LL n, m, we[maxm]; 42 LL num; 43 LL dist[maxn]; 44 bool vis[maxn]; 45 46 void init() 47 { 48 memset(head, -1, sizeof(head)); 49 tot = 0; 50 } 51 52 void AddEdge(LL u, LL v, LL w, LL w2) 53 { 54 edge[tot] = Edge(v, head[u], w); 55 head[u] = tot++; 56 edge[tot] = Edge(u, head[v], w2); 57 head[v] = tot++; 58 } 59 60 inline LL get_row(LL x, LL y) 61 { 62 return x * (m + m - 1) + y; 63 } 64 65 inline LL get_col(LL x, LL y) 66 { 67 return x * (m + m - 1) + y + m - 1; 68 } 69 70 LL Dijkstra() 71 { 72 priority_queue<HeapNode> que; 73 memset(dist, INF, sizeof(dist)); 74 memset(vis, false, sizeof(vis)); 75 for (LL i = 0; i < n - 1; i++) 76 { 77 LL id = get_col(i, 0); 78 dist[id] = we[id]; 79 que.push((HeapNode){id, dist[id]}); 80 } 81 for (LL j = 0; j < m - 1; j++) 82 { 83 LL id = get_row(n - 1, j); 84 dist[id] = we[id]; 85 que.push((HeapNode){id, dist[id]}); 86 } 87 while (!que.empty()) 88 { 89 HeapNode x = que.top(); 90 que.pop(); 91 if (vis[x.u]) 92 continue; 93 LL u = x.u; 94 vis[u] = true; 95 for (LL i = head[u]; i != -1; i = edge[i].next) 96 { 97 LL v = edge[i].to; 98 if (!vis[v] && dist[v] > dist[u] + edge[i].w) 99 { 100 dist[v] = dist[u] + edge[i].w; 101 que.push((HeapNode){v, dist[v]}); 102 } 103 } 104 } 105 106 LL ans = Inf; 107 for (LL j = 0; j < m - 1; j++) 108 { 109 ans = min(ans, dist[get_row(0, j)]); 110 } 111 for (LL i = 0; i < n - 1; i++) 112 { 113 ans = min(ans, dist[get_col(i, m - 1)]); 114 } 115 116 return ans; 117 } 118 119 LL iCase; 120 121 int main() 122 { 123 //ios::sync_with_stdio(false); 124 //cin.tie(0); 125 //freopen("input.txt", "r", stdin); 126 //freopen("output.txt", "w", stdout); 127 while (~scanf("%lld%lld", &n, &m) && (n || m)) 128 { 129 init(); 130 for (LL i = 0; i < n; i++) 131 { 132 for (LL j = 0; j < m - 1; j++) 133 { 134 scanf("%lld", &we[get_row(i, j)]); 135 } 136 } 137 for (LL i = 0; i < n - 1; i++) 138 { 139 for (LL j = 0; j < m; j++) 140 { 141 scanf("%lld", &we[get_col(i, j)]); 142 } 143 } 144 num = n * (m - 1) + m * (n - 1); 145 LL val; 146 for (LL i = 0; i < n - 1; i++) 147 { 148 for (LL j = 0; j < m - 1; j++) 149 { 150 scanf("%lld", &val); 151 int a = get_row(i, j), b = get_row(i + 1, j); 152 int c = get_col(i, j), d = get_col(i, j + 1); 153 AddEdge(num, a, we[a], val); 154 AddEdge(num, b, we[b], val); 155 AddEdge(num, c, we[c], val); 156 AddEdge(num, d, we[d], val); 157 AddEdge(d, a, we[a], we[d]); 158 AddEdge(b, c, we[c], we[b]); 159 num++; 160 } 161 } 162 LL ans = Dijkstra(); 163 printf("Case %d: Minimum = %lld ", ++iCase, ans); 164 } 165 return 0; 166 }