UVALive - 3661 - Animal Run(最大流最小割定理——平面图最小割)

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\n", ++iCase, ans);
164     }
165     return 0;
166 }

猜你喜欢

转载自www.cnblogs.com/npugen/p/10889415.html