BZOJ 1001: [BeiJing2006]狼抓兔子(s-t平面图+最短路求最小割)

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来存储,最后只好改用数组来存储。

  1 /**************************************************************
  2     Problem: 1001
  3     User: Vortex
  4     Language: C++
  5     Result: Accepted
  6     Time:2112 ms
  7     Memory:89184 kb
  8 ****************************************************************/
  9  
 10 #include<iostream>
 11 #include<algorithm>
 12 #include<cstring>
 13 #include<cstdio>
 14 #include<sstream>
 15 #include<vector>
 16 #include<stack>
 17 #include<queue>
 18 #include<cmath>
 19 #include<map>
 20 #include<set>
 21 using namespace std;
 22 typedef long long ll;
 23 typedef pair<int,int> pll;
 24 const int INF = 0x3f3f3f3f;
 25 const int maxn = 1000*1000*2 + 5;
 26  
 27 int n, m;
 28 int num;
 29 int src, dst;
 30  
 31 struct Edge
 32 {
 33     int v, w;
 34     int next;
 35 }edge[3*maxn];
 36  
 37 struct HeapNode
 38 {
 39     int d, u;
 40     HeapNode(int x, int y) :d(x), u(y){}
 41     bool operator < (const HeapNode& rhs) const{
 42         return d > rhs.d;
 43     }
 44 };
 45  
 46 int head[maxn];
 47 bool done[maxn];
 48 int d[maxn];
 49  
 50 void AddEdges(int u, int v, int w)
 51 {
 52     edge[num].v=v ;edge[num].w=w ;
 53     edge[num].next=head[u] ;head[u]=num++ ;
 54 }
 55  
 56 void dijkstra(int s)
 57 {
 58     priority_queue<HeapNode> Q;
 59     for (int i = 0; i <=dst; i++)    d[i] = INF;
 60     d[s] = 0;
 61     memset(done, 0, sizeof(done));
 62     Q.push(HeapNode(0,s));
 63     while (!Q.empty())
 64     {
 65         HeapNode x = Q.top(); Q.pop();
 66         int u = x.u;
 67         if (done[u]) continue;
 68         done[u] = true;
 69         for (int i = head[u]; i!=-1; i=edge[i].next)
 70         {
 71             if (d[edge[i].v] > d[u] + edge[i].w)
 72             {
 73                 d[edge[i].v] = d[u] + edge[i].w;
 74                 Q.push(HeapNode(d[edge[i].v],edge[i].v));
 75             }
 76         }
 77     }
 78 }
 79  
 80 int main()
 81 {
 82     //freopen("in.txt","r",stdin);
 83     while(~scanf("%d%d",&n,&m))
 84     {
 85         src=0,dst=2*(n-1)*(m-1)+1;
 86  
 87         memset(head,-1,sizeof(head));
 88         num=0;
 89  
 90         for(int i=1;i<=n;i++)
 91         {
 92             for(int j=1;j<m;j++)
 93             {
 94                 int u,v,w;
 95                 scanf("%d",&w);
 96                 if(i==1)  u=src;
 97                 else u=(2*(i-1)-1)*(m-1)+j;
 98                 if(i==n)  v=dst;
 99                 else v=(2*(i-1))*(m-1)+j;
100                 AddEdges(u,v,w);
101                 AddEdges(v,u,w);
102             }
103         }
104  
105         for(int i=1;i<n;i++)
106         {
107             for(int j=1;j<=m;j++)
108             {
109                 int u,v,w;
110                 scanf("%d",&w);
111                 if(j==1)  u=dst;
112                 else u=(2*(i-1))*(m-1)+j-1;
113                 if(j==m)  v=src;
114                 else v=(2*(i-1))*(m-1)+j-1+m;
115                 AddEdges(u,v,w);
116                 AddEdges(v,u,w);
117             }
118         }
119  
120         for(int i=1;i<n;i++)
121         {
122             for(int j=1;j<m;j++)
123             {
124                 int u,v,w;
125                 scanf("%d",&w);
126                 u=(2*(i-1))*(m-1)+j;
127                 v=(2*(i-1)+1)*(m-1)+j;
128                 AddEdges(u,v,w);
129                 AddEdges(v,u,w);
130             }
131         }
132  
133         dijkstra(src);
134         printf("%d\n",d[dst]);
135     }
136     return 0;
137 }
posted @ 2017-07-31 21:58  Kayden_Cheung  阅读(272)  评论(0编辑  收藏  举报
//目录