[BeiJing2006]狼抓兔子

Description

现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: 左上角点为(1,1),右下角点为(N,M)(上图中N=4,M=5).有以下三种类型的道路 1:(x,y)<==>(x+1,y) 2:(x,y)<==>(x,y+1) 3:(x,y)<==>(x+1,y+1) 道路上的权值表示这条路上最多能够通过的兔子数,道路是无向的. 左上角和右下角为兔子的两个窝,开始时所有的兔子都聚集在左上角(1,1)的窝里,现在它们要跑到右下解(N,M)的窝中去,狼王开始伏击这些兔子.当然 为了保险起见,如果一条道路上最多通过的兔子数为K,狼王需要安排同样数量的K只狼,才能完全封锁这条道路,你需要帮助狼王安排一个伏击方案,使得在将兔 子一网打尽的前提下,参与的狼的数量要最小。因为狼还要去找喜羊羊麻烦.

Input

第一行为N,M.表示网格的大小,N,M均小于等于1000.接下来分三部分 第一部分共N行,每行M-1个数,表示横向道路的权值. 第二部分共N-1行,每行M个数,表示纵向道路的权值. 第三部分共N-1行,每行M-1个数,表示斜向道路的权值. 输入文件保证不超过10M

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

Sample Output

14
 
 
 
 
 
平面图最大流转化为最短路问题。
heap+dijkstra优化。
第一次使用STL中的heap操作,太简便了,不过也编了个最小堆。
 
STL调用<algorithm>中的pop_heap(begin,last,cmp)去除最小元素,push_heap(begin,last,cmp)将last-1上的元素加入堆中:
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<fstream>
  6 #define Edgsize 6000000
  7 #define Nodesize 2000000
  8 #define Maxint 100000000
  9 
 10 using namespace std;
 11 //ifstream cin("cin.in");
 12 
 13 int n,m,S,T;
 14 int to[Edgsize],next[Edgsize],weight[Edgsize],head[Nodesize],edgs=0;
 15 int dis[Nodesize];
 16 typedef struct {
 17         int num,d;
 18         }Heap;Heap heap[Nodesize],temp;
 19        
 20 int seat(int x,int y,int z){
 21     if(z==1) return (x-1)*(m-1)+y;
 22     else return (n-1)*(m-1)+(x-1)*(m-1)+y;
 23     }
 24 
 25 void Addedg(int u,int v,int d){
 26      edgs++;to[edgs]=v;next[edgs]=head[u];weight[edgs]=d;head[u]=edgs;
 27      edgs++;to[edgs]=u;next[edgs]=head[v];weight[edgs]=d;head[v]=edgs;
 28      }
 29 
 30 int ans=Maxint;
 31 void Init(){
 32      //cout<<" sdf";system("pause"); 
 33      cin>>n>>m;
 34      
 35      S=(n-1)*(m-1)*2+1;T=S+1;
 36      memset(head,-1,sizeof(head));
 37      
 38      int d;
 39      
 40      if(n==1||m==1)
 41      {
 42        for(int i=1;i<n||i<m;++i)
 43        {cin>>d;if(d<ans) ans=d;}return ;
 44                    }
 45      
 46      for(int i=1;i<=n;++i)
 47      for(int j=1;j<m;++j)
 48      {
 49        cin>>d;
 50        if(i==1) Addedg(S,seat(1,j,1),d);
 51        else if(i==n) Addedg(seat(i-1,j,2),T,d);
 52        else Addedg(seat(i-1,j,2),seat(i,j,1),d);
 53              }
 54      
 55      for(int i=1;i<n;++i)
 56      for(int j=1;j<=m;++j)
 57      {
 58        cin>>d;
 59        if(j==1) Addedg(seat(i,j,2),T,d);
 60        else if(j==m) Addedg(seat(i,j-1,1),S,d);
 61        else Addedg(seat(i,j-1,1),seat(i,j,2),d);
 62              }
 63      
 64      for(int i=1;i<n;++i)
 65      for(int j=1;j<m;++j)
 66      {
 67        cin>>d;
 68        Addedg(seat(i,j,1),seat(i,j,2),d);
 69              }
 70      
 71      }
 72 
 73 bool cmp(Heap a,Heap b){
 74      return a.d>b.d;
 75      }
 76 
 77 int size=1;
 78 void Dijkstra(){
 79      for(int i=1;i<=T;++i)
 80      dis[i]=Maxint;
 81      
 82      if(n==1||m==1) {cout<<0<<endl;return ;}
 83      
 84      dis[S]=0;heap[1].num=S;heap[1].d=0;
 85      while(size)
 86      {
 87        temp=heap[1];
 88      //  if(heap[1].num==T) {cout<<dis[T]<<endl;return ;}
 89        pop_heap(heap+1,heap+1+size,cmp);
 90        size--;//cout<<size<<"  dsfg "<<endl;
 91        
 92        for(int it=head[temp.num];it!=-1;it=next[it])
 93        if(dis[to[it]]>dis[temp.num]+weight[it])
 94        {
 95          
 96          dis[to[it]]=dis[temp.num]+weight[it];
 97         // cout<<from[it]<<"  "<<to[it]<<"  "<<dis[to[it]]<<endl;
 98          size++;
 99          heap[size].num=to[it];heap[size].d=dis[to[it]];
100         
101          push_heap(heap+1,heap+1+size,cmp);
102                }
103                 }
104      cout<<dis[T]<<endl;
105      
106      }
107 
108 int main()
109 {
110     Init();
111     if(ans!=Maxint) {cout<<ans<<endl;return 0;}
112     
113     Dijkstra();
114     //system("pause");
115     return 0;
116     }
 
手写堆:
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<fstream>
  6 #define Edgsize 6000000
  7 #define Nodesize 2000000
  8 #define Maxint 100000000
  9 
 10 using namespace std;
 11 //ifstream cin("cin.in");
 12 
 13 int n,m,S,T;
 14 int to[Edgsize],next[Edgsize],weight[Edgsize],head[Nodesize],edgs=0;
 15 int dis[Nodesize];
 16 typedef struct {
 17         int num,d;
 18         }Heap;Heap heap[Nodesize],temp;
 19        
 20 int seat(int x,int y,int z){
 21     if(z==1) return (x-1)*(m-1)+y;
 22     else return (n-1)*(m-1)+(x-1)*(m-1)+y;
 23     }
 24 
 25 void Addedg(int u,int v,int d){
 26      edgs++;to[edgs]=v;next[edgs]=head[u];weight[edgs]=d;head[u]=edgs;
 27      edgs++;to[edgs]=u;next[edgs]=head[v];weight[edgs]=d;head[v]=edgs;
 28      }
 29 
 30 int ans=Maxint;
 31 void Init(){
 32      //cout<<" sdf";system("pause"); 
 33      cin>>n>>m;
 34      
 35      S=(n-1)*(m-1)*2+1;T=S+1;
 36      memset(head,-1,sizeof(head));
 37      
 38      int d;
 39      
 40      if(n==1||m==1)
 41      {
 42        for(int i=1;i<n||i<m;++i)
 43        {cin>>d;if(d<ans) ans=d;}return ;
 44                    }
 45      
 46      for(int i=1;i<=n;++i)
 47      for(int j=1;j<m;++j)
 48      {
 49        cin>>d;
 50        if(i==1) Addedg(S,seat(1,j,1),d);
 51        else if(i==n) Addedg(seat(i-1,j,2),T,d);
 52        else Addedg(seat(i-1,j,2),seat(i,j,1),d);
 53              }
 54      
 55      for(int i=1;i<n;++i)
 56      for(int j=1;j<=m;++j)
 57      {
 58        cin>>d;
 59        if(j==1) Addedg(seat(i,j,2),T,d);
 60        else if(j==m) Addedg(seat(i,j-1,1),S,d);
 61        else Addedg(seat(i,j-1,1),seat(i,j,2),d);
 62              }
 63      
 64      for(int i=1;i<n;++i)
 65      for(int j=1;j<m;++j)
 66      {
 67        cin>>d;
 68        Addedg(seat(i,j,1),seat(i,j,2),d);
 69              }
 70      
 71      }
 72      
 73      
 74 int len=1;
 75 void Down(int site){
 76      
 77      while(1)
 78      {//cout<<"down"<<endl;
 79        int least=site,left=2*site,right=2*site+1;
 80        if(left<=len&&heap[left].d<heap[least].d) least=left;
 81        if(right<=len&&heap[right].d<heap[least].d) least=right;
 82        
 83        if(least!=site)
 84        {
 85          swap(heap[site],heap[least]);
 86          site=least;  
 87                       }
 88        else break;
 89              
 90              }
 91      
 92      }
 93 
 94 void Up(int site){
 95      int f=site/2;
 96      while(f>0&&heap[site].d<heap[f].d)
 97      {
 98        swap(heap[site],heap[f]);
 99        site=f;
100        f/=2;   
101                }
102      }
103 
104 void Delete_min(int l){
105      if(l==0) return ;
106      swap(heap[1],heap[l+1]);
107      Down(1);
108      }
109 
110 
111 void Dijkstra(){
112      for(int i=1;i<=T;++i)
113      dis[i]=Maxint;
114      heap[1].num=S;heap[1].d=0;dis[S]=0;
115      
116      for(int i=1;i<=T&&len>0;++i)
117      {
118        temp=heap[1];
119        len--;  
120        Delete_min(len); //cout<<"  sdfg"<<endl; 
121        
122        for(int j=head[temp.num];j!=-1;j=next[j])
123        if(dis[to[j]]>dis[temp.num]+weight[j])
124        {
125          dis[to[j]]=dis[temp.num]+weight[j];
126          len++;//cout<<len<<"  "<<endl;
127          heap[len].num=to[j];heap[len].d=dis[to[j]];  
128          Up(len);
129                }   
130             // system("pause");
131              }
132      cout<<dis[T]<<endl;
133      }
134 
135 int main(){
136     Init();///cout<<n<<" "<<m<<endl;
137     if(ans!=Maxint) {cout<<ans<<endl;return 0;}
138     Dijkstra();
139     //system("pause");
140     return 0;
141     
142     }
 
原文地址:https://www.cnblogs.com/noip/p/2941134.html