[bzoj1001][BJOI2006]狼抓兔子——最大流转最短路,平面图
2017-02-15 20:02
459 查看
题目描述:
给定一个平面图,求最小割。
题解:
本题是一道经典题.
周冬Orz的论文是很好的研究资料。
这道题点太多,所以直接跑dinic无疑会超时。
我们观察原图,发现原图是一个平面图。
什么是平面图呢?平面图就是可以画在平面上,边没有交错的图。
平面图有几个很吼的性质:
- 欧拉定理(欧拉的定理真多。。):如果平面图把平面分为f个面,有n个点,m条边,那么我们有:
\[f = m - n + 2\] - 任何一个平面图的对偶图还是一个平面图。
这里的对偶图指的是把原图中的面当作点,边还是边进行构图得到的图。
我们很容易发现,对偶图中的一个环就是原图的一个最小割。
但是,显然我们求环还是比较麻烦的。
我们考察原图性质,
如果在st中间连一条新边,显然新图还是平面图,同时会比原图多出一个面,我们称之为副面,
对于这个新图,我们构对偶图,同时令副面和最大的面一个为起点,一个为终点,显然对偶图中的最短路就是原图的一个最小割。
然后spfa解决就好辣。
本题最恶心的点在于建对偶图。
代码
#include <bits/stdc++.h> using namespace std; const int maxn = (1000 * 1000 + 50) * 2; int n, m, nm, s, t; int dist[maxn]; struct edge { int to, weigh; }; vector<edge> G[maxn]; void add_edge(int from, int to, int weigh) { G[from].push_back((edge){to, weigh}); G[to].push_back((edge){from, weigh}); } void spfa() { queue<int> q; memset(dist, 127, sizeof(dist)); dist[s] = 0; q.push(s); int inq[maxn]; memset(inq, 0, sizeof(inq)); inq[s] = 1; while (!q.empty()) { int u = q.front(); q.pop(); inq[u] = 0; for (int i = 0; i < G[u].size(); i++) { edge &e = G[u][i]; if (dist[e.to] > dist[u] + e.weigh) { dist[e.to] = dist[u] + e.weigh; if (inq[e.to] == 0) { q.push(e.to); inq[e.to] = 1; } } } } } int main() { scanf("%d%d", &n, &m); nm = (n * m - m - n + 1) << 1; s = 0, t = nm + 1; //横向边 int x; for (int j = 1; j < m; j++) { scanf("%d", &x); add_edge(j, t, x); } for (int i = 1; i < (n - 1); i++) { for (int j = 1; j < m; j++) { scanf("%d", &x); add_edge((i << 1) * (m - 1) + j, ((i << 1) - 1) * (m - 1) + j, x); } } for (int j = 1; j < m; j++) { scanf("%d", &x); add_edge(((n << 1) - 3) * (m - 1) + j, 0, x); } //纵向边 for (int i = 0; i < n - 1; i++) { for (int j = 1; j <= m; j++) { scanf("%d", &x); if (j == 1) add_edge(0, (i << 1) * (m - 1) + m, x); else if (j == m) add_edge((i << 1 | 1) * (m - 1), t, x); else add_edge((i << 1) * (m - 1) + j - 1, (i << 1) * (m - 1) + j + m - 1, x); } } //斜 for (int i = 0; i < n - 1; i++) { for (int j = 1; j < m; j++) { scanf("%d", &x); add_edge((i << 1 | 1) * (m - 1) + j, (i << 1) * (m - 1) + j, x); } } spfa(); printf("%d", dist[t]); }
相关文章推荐
- bzoj1001 [BeiJing2006]狼抓兔子(最小割/平面图最大流转对偶图最短路)
- [BJOI2006] [BZOJ1001] 狼抓兔子|最大流|最短路
- BZOJ 1001([BeiJing2006]狼抓兔子-最大流转对偶图最短路)
- BZOJ 1001([BeiJing2006]狼抓兔子-最大流转对偶图最短路)
- 【平面图】【最小割】【最短路】【Heap-Dijkstra】bzoj1001 [BeiJing2006]狼抓兔子
- BZOJ 1001 [BeiJing2006] 狼抓兔子(平面图最大流)
- 【BZOJ 1001】狼抓兔子 【S-T平面图最大流转对偶图最短路】
- BZOJ1001 [BeiJing2006]狼抓兔子(平面图最小割转最短路)
- BZOJ 1001 [BeiJing2006] 狼抓兔子(平面图最大流)
- [平面图转最短路]BZOJ1001:[BeiJing2006]狼抓兔子
- 【平面图转对偶图】【最短路】【Beijing 2006】【bzoj 1001】狼抓兔子
- 【bzoj1001】【最短路】【对偶图】【最大流转最小割】狼抓兔子题解
- BZOJ1001 BJOI2006狼抓兔子(最小割+最短路)
- BZOJ 1001: [BeiJing2006]狼抓兔子(s-t平面图+最短路求最小割)
- BZOJ 1001: [BeiJing2006]狼抓兔子(平面图最小割转对偶图最短路)
- bzoj 1001: [BeiJing2006]狼抓兔子(s-t平面图求最大流)
- 【BZOJ1001】【Beijing2006】狼抓兔子(平面图转对偶图:最小割+最短路)
- BZOJ 1001 狼抓兔子 平面图上的最大流--跑最短路
- [BZOJ1001] [BJOI2006] 狼抓兔子
- BZOJ 1001 平面图与对偶图的转化 最短路Or最大流