BZOJ 1001: [BeiJing2006]狼抓兔子(s-t平面图+最短路求最小割)
2017-07-31 21:58
597 查看
http://www.lydsy.com/JudgeOnline/problem.php?id=1001
题意:
思路:
这道题目是最小割题目,但是吧你直接套用Dinic是会超时的。
这里有种很奇妙的做法啊,具体可以参见论文:《浅析最大最小定理在信息学竞赛中的应用》--周冬
S-T平面图:首先是一平面图(满足欧拉公式与存在对偶图),且源点S,汇点T在边界上。将S-T连线,将最外面的一个大面(无限大)一分为二了,一个为S,一个为T。然后将每条边两边的面相连,权值就是该边权值。最后跑最短路,它经过的路径就是原图中的边,最短路也就变成了最小割。
http://blog.csdn.net/ahero_happy/article/details/6637214该博主讲得不错,可以看一下。
一开始写了个最普通的最短路,结果超时。然后写了带队优化的,超内存了,因为用了vector来存储,最后只好改用数组来存储。
题意:
思路:
这道题目是最小割题目,但是吧你直接套用Dinic是会超时的。
这里有种很奇妙的做法啊,具体可以参见论文:《浅析最大最小定理在信息学竞赛中的应用》--周冬
S-T平面图:首先是一平面图(满足欧拉公式与存在对偶图),且源点S,汇点T在边界上。将S-T连线,将最外面的一个大面(无限大)一分为二了,一个为S,一个为T。然后将每条边两边的面相连,权值就是该边权值。最后跑最短路,它经过的路径就是原图中的边,最短路也就变成了最小割。
http://blog.csdn.net/ahero_happy/article/details/6637214该博主讲得不错,可以看一下。
一开始写了个最普通的最短路,结果超时。然后写了带队优化的,超内存了,因为用了vector来存储,最后只好改用数组来存储。
/************************************************************** Problem: 1001 User: Vortex Language: C++ Result: Accepted Time:2112 ms Memory:89184 kb ****************************************************************/ #include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<sstream> #include<vector> #include<stack> #include<queue> #include<cmath> #include<map> #include<set> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int INF = 0x3f3f3f3f; const int maxn = 1000*1000*2 + 5; int n, m; int num; int src, dst; struct Edge { int v, w; int next; }edge[3*maxn]; struct HeapNode { int d, u; HeapNode(int x, int y) :d(x), u(y){} bool operator < (const HeapNode& rhs) const{ return d > rhs.d; } }; int head[maxn]; bool done[maxn]; int d[maxn]; void AddEdges(int u, int v, int w) { edge[num].v=v ;edge[num].w=w ; edge[num].next=head[u] ;head[u]=num++ ; } void dijkstra(int s) { priority_queue<HeapNode> Q; for (int i = 0; i <=dst; i++) d[i] = INF; d[s] = 0; memset(done, 0, sizeof(done)); Q.push(HeapNode(0,s)); while (!Q.empty()) { HeapNode x = Q.top(); Q.pop(); int u = x.u; if (done[u]) continue; done[u] = true; for (int i = head[u]; i!=-1; i=edge[i].next) { if (d[edge[i].v] > d[u] + edge[i].w) { d[edge[i].v] = d[u] + edge[i].w; Q.push(HeapNode(d[edge[i].v],edge[i].v)); } } } } int main() { //freopen("in.txt","r",stdin); while(~scanf("%d%d",&n,&m)) { src=0,dst=2*(n-1)*(m-1)+1; memset(head,-1,sizeof(head)); num=0; for(int i=1;i<=n;i++) { for(int j=1;j<m;j++) { int u,v,w; scanf("%d",&w); if(i==1) u=src; else u=(2*(i-1)-1)*(m-1)+j; if(i==n) v=dst; else v=(2*(i-1))*(m-1)+j; AddEdges(u,v,w); AddEdges(v,u,w); } } for(int i=1;i<n;i++) { for(int j=1;j<=m;j++) { int u,v,w; scanf("%d",&w); if(j==1) u=dst; else u=(2*(i-1))*(m-1)+j-1; if(j==m) v=src; else v=(2*(i-1))*(m-1)+j-1+m; AddEdges(u,v,w); AddEdges(v,u,w); } } for(int i=1;i<n;i++) { for(int j=1;j<m;j++) { int u,v,w; scanf("%d",&w); u=(2*(i-1))*(m-1)+j; v=(2*(i-1)+1)*(m-1)+j; AddEdges(u,v,w); AddEdges(v,u,w); } } dijkstra(src); printf("%d\n",d[dst]); } return 0; }
相关文章推荐
- 【BZOJ1001】【Beijing2006】狼抓兔子(平面图转对偶图:最小割+最短路)
- 【平面图】【最小割】【最短路】【Heap-Dijkstra】bzoj1001 [BeiJing2006]狼抓兔子
- BZOJ1001 [BeiJing2006]狼抓兔子(平面图最小割转最短路)
- bzoj1001 [BeiJing2006]狼抓兔子(最小割/平面图最大流转对偶图最短路)
- BZOJ 1001: [BeiJing2006]狼抓兔子(平面图最小割转对偶图最短路)
- bzoj 1001: [BeiJing2006]狼抓兔子 平面图最小割
- 【平面图转对偶图】【最短路】【Beijing 2006】【bzoj 1001】狼抓兔子
- [平面图转最短路]BZOJ1001:[BeiJing2006]狼抓兔子
- 【最小割+对偶图=最短路】BZOJ1001 [BeiJing2006]狼抓兔子
- 【平面图最小割】BZOJ1001- [BeiJing2006]狼抓兔子
- 【BZOJ1001】[BeiJing2006]狼抓兔子【最小割】【最短路】【对偶图】
- bzoj 1001: [BeiJing2006]狼抓兔子 对偶图最短路-(最小割)
- [最小割+对偶建图+最短路] BZOJ1001: [BeiJing2006]狼抓兔子
- [bzoj 1001][Beijing2006]狼抓兔子 (最小割+对偶图+最短路)
- 【最小割->最短路】BZOJ1001(BeiJing2006)[狼抓兔子]题解
- 【BZOJ1001】狼抓兔子,平面图转对偶图(从最小割到最短路)
- BZOJ 1001 [BeiJing2006] 狼抓兔子(平面图最大流)
- BZOJ1001: [BeiJing2006]狼抓兔子 [最小割 | 对偶图+spfa]
- 对偶图 && 【BZOJ】1001: [BeiJing2006]狼抓兔子(对偶图+最短路)
- 【BZOJ 1001:[BeiJing2006]狼抓兔子 最小割转对偶图堆优化dij