zoukankan      html  css  js  c++  java
  • [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     }
     
  • 相关阅读:
    POJ2778 DNA Sequence AC自动机上dp
    codeforces732F Tourist Reform 边双联通分量
    codeforces786B Legacy 线段树优化建图
    洛谷P3588 PUS 线段树优化建图
    codeforces1301D Time to Run 模拟
    codeforces1303B National Project 二分或直接计算
    codeforces1303C Perfect Keyboard 模拟或判断欧拉路
    codeforces1303D Fill The Bag 二进制应用+贪心
    python之路——使用python操作mysql数据库
    python之路——mysql索引原理
  • 原文地址:https://www.cnblogs.com/noip/p/2941134.html
Copyright © 2011-2022 走看看