1. 程式人生 > >BZOJ_2001_[BeiJing2006]狼抓兔子_最小割轉對偶圖

BZOJ_2001_[BeiJing2006]狼抓兔子_最小割轉對偶圖

int ng2 std lan pac href can problem http

BZOJ_2001_[BeiJing2006]狼抓兔子

題意:http://www.lydsy.com/JudgeOnline/problem.php?id=1001

分析:思路同NOI2010海拔。

註意無向圖。

代碼:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <algorithm>
 4 #include <queue>
 5 using namespace std;
 6 #define S (0)
 7 #define T ((n-1)*(m-1)*2+1)
 8 #define H (2*m-2)
 9
priority_queue < pair<int,int> > q; 10 #define N 3000200 11 int head[N],nxt[N*10],to[N*10],val[N*10],cnt,n,m; 12 int dis[N],vis[N]; 13 inline void add(int u,int v,int w){ 14 to[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt;val[cnt]=w; 15 to[++cnt]=u;nxt[cnt]=head[v];head[v]=cnt;val[cnt]=w; 16 }
17 int main(){ 18 scanf("%d%d",&n,&m); 19 int x; 20 if(n==1||m==1){ 21 int ans=1<<30; 22 if(n>m)swap(n,m); 23 for(int i=1;i<m;i++){ 24 scanf("%d",&x); 25 ans=min(ans,x); 26 } 27 printf("%d",ans);return 0
; 28 } 29 for(int i=1;i<=n;i++){ 30 for(int j=1;j<m;j++){ 31 scanf("%d",&x); 32 if(i==1)add(S,2*j,x); 33 else if(i<n)add((i-2)*H+2*j-1,(i-1)*H+2*j,x); 34 else add((i-2)*H+2*j-1,T,x); 35 } 36 } 37 for(int i=1;i<n;i++){ 38 for(int j=1;j<=m;j++){ 39 scanf("%d",&x); 40 if(j==1)add((i-1)*H+1,T,x); 41 else if(j<m)add((i-1)*H+2*j-1,(i-1)*H+2*j-2,x); 42 else add(S,(i-1)*H+2*j-2,x); 43 } 44 } 45 for(int i=1;i<n;i++){ 46 for(int j=1;j<m;j++){ 47 scanf("%d",&x); 48 add((i-1)*H+2*j,(i-1)*H+2*j-1,x); 49 } 50 } 51 memset(dis,0x3f,sizeof(dis)); 52 dis[S]=0; 53 q.push(make_pair(dis[S],S)); 54 while(!q.empty()){ 55 int x=q.top().second;q.pop(); 56 if(vis[x])continue; 57 vis[x]=1; 58 for(int i=head[x];i;i=nxt[i]){ 59 if(dis[to[i]]>dis[x]+val[i]){ 60 dis[to[i]]=dis[x]+val[i]; 61 q.push(make_pair(-dis[to[i]],to[i])); 62 } 63 } 64 } 65 printf("%d",dis[T]); 66 }

BZOJ_2001_[BeiJing2006]狼抓兔子_最小割轉對偶圖