题意:现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: 左上角点为(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