• [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     }
     
  • 相关阅读:
    USACO 2008 Mar Silver 3.River Crossing 动态规划水题
    常见经验总结
    Ikki's Story IV
    洛谷P1993 小K的农场_差分约束_dfs跑SPFA
    洛谷P3275 [SCOI2011]糖果_差分约束_判负环
    Integer Intervals POJ
    洛谷 P2365 任务安排_代价提前计算 + 好题
    [NOI2005]瑰丽华尔兹 动态规划 + 单调队列
    Shoot the Bullet ZOJ
    background-clip 和 background-origin
  • 原文地址:https://www.cnblogs.com/noip/p/2941134.html
Copyright © 2020-2023  润新知