zybbs 1001 狼抓兔子 平面图最大流

题意:现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: 左上角点为(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只狼,才能完全封锁这条道路,你需要帮助狼王安排一个伏击方案,使得在将兔子一网打尽的前提下,参与的狼的数量要最小。因为狼还要去找喜羊羊麻烦.

思路:平面图最大路

对偶图最短路径

P.S. m=1或者n=1要特判

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<cstring>
  5 #include<queue>
  6 #include<algorithm>
  7 using namespace std;
  8 #define MAXN 2000001
  9 #define MAXM 6000001
 10 int n,m,top=0;
 11 int edge[4][1100][1100],t,d[MAXN];
 12 bool use[MAXN];
 13 struct node
 14 {
 15     int num,weight;
 16     node *next;
 17 };
 18 node memo[MAXM],*graph[MAXN];
 19 void add(int x,int y,int z)
 20 {
 21     node *p=&memo[top++];
 22     p->num=y; p->next=graph[x]; p->weight=z; graph[x]=p;
 23     p=&memo[top++];
 24     p->num=x; p->next=graph[y]; p->weight=z; graph[y]=p;
 25 }
 26 int Dijkstra()
 27 {
 28     memset(d,0x3f,sizeof(d));
 29     memset(use,0,sizeof(use));
 30     priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > Q;
 31     Q.push(make_pair(0,0));
 32     pair<int,int> q;
 33     int u,v;
 34     d[0]=0;
 35     while(use[t]==0)
 36     {
 37         q=Q.top(); Q.pop();
 38         while(use[q.second])
 39         {
 40             q=Q.top(); Q.pop();
 41         }
 42         u=q.second;
 43         //cout<<u<<" "<<d[u]<<endl;
 44         use[u]=1;
 45         for(node *p=graph[u];p;p=p->next)
 46         {
 47             v=p->num;
 48             if(!use[v]&&d[u]+p->weight<d[v])
 49             {
 50                 d[v]=d[u]+p->weight;
 51                 Q.push(make_pair(d[v],v));
 52             }
 53         }
 54     }
 55     return d[t];
 56 }
 57                  
 58 int main()
 59 {
 60     int i,j;
 61     scanf("%d%d",&n,&m);
 62     for(i=1;i<=n;i++)
 63         for(j=1;j<m;j++)
 64             scanf("%d",&edge[1][i][j]);
 65     for(i=1;i<n;i++)
 66         for(j=1;j<=m;j++)
 67             scanf("%d",&edge[2][i][j]);
 68     for(i=1;i<n;i++)
 69         for(j=1;j<m;j++)
 70             scanf("%d",&edge[3][i][j]);
 71     if(n==1)
 72     {
 73         int MIN=987654321;
 74         for(i=1;i<m;i++)
 75             MIN=min(MIN,edge[1][1][i]);
 76         printf("%d\n",MIN);
 77         return 0;
 78     }
 79     else if(m==1)
 80     {
 81         int MIN=987654321;
 82         for(i=1;i<n;i++)
 83             MIN=min(MIN,edge[2][i][1]);
 84         printf("%d\n",MIN);
 85         return 0;
 86     }
 87     t=2*(n-1)*(m-1)+1;
 88     for(i=1;i<m;i++)
 89         add(0,i,edge[1][1][i]);
 90     for(i=1;i<n;i++)
 91         add(0,(2*i-1)*(m-1),edge[2][i][m]);
 92     for(i=1;i<m;i++)
 93         add(t,(2*n-3)*(m-1)+i,edge[1][n][i]);
 94     for(i=1;i<n;i++)
 95         add(t,(2*i-1)*(m-1)+1,edge[2][i][1]);
 96     for(i=1;i<n;i++)
 97         for(j=1;j<m-1;j++)
 98             add((2*i-2)*(m-1)+j,(2*i-1)*(m-1)+j+1,edge[2][i][j+1]);
 99     for(i=1;i<n-1;i++)
100         for(j=1;j<m;j++)
101             add((2*i-1)*(m-1)+j,2*i*(m-1)+j,edge[1][i+1][j]);
102     for(i=1;i<n;i++)
103         for(j=1;j<m;j++)
104             add((2*i-2)*(m-1)+j,(2*i-1)*(m-1)+j,edge[3][i][j]);
105     //for(i=0;i<=t;i++)
106     //for(node *p=graph[i];p;p=p->next)
107         //cout<<i<<" "<<p->num<<" "<<p->weight<<endl;
108     printf("%d\n",Dijkstra());
109     return 0;
110 }
111 
112         
原文地址:https://www.cnblogs.com/myoi/p/2485997.html