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 }