BZOJ_2001_[BeiJing2006]狼抓兔子_最小割转对偶图
BZOJ_2001_[BeiJing2006]狼抓兔子
题意:http://www.lydsy.com/JudgeOnline/problem.php?id=1001
分析:思路同NOI2010海拔。
注意无向图。
代码:
#include <stdio.h> #include <string.h> #include <algorithm> #include <queue> using namespace std; #define S (0) #define T ((n-1)*(m-1)*2+1) #define H (2*m-2) priority_queue < pair<int,int> > q; #define N 3000200 int head[N],nxt[N*10],to[N*10],val[N*10],cnt,n,m; int dis[N],vis[N]; inline void add(int u,int v,int w){ to[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt;val[cnt]=w; to[++cnt]=u;nxt[cnt]=head[v];head[v]=cnt;val[cnt]=w; } int main(){ scanf("%d%d",&n,&m); int x; if(n==1||m==1){ int ans=1<<30; if(n>m)swap(n,m); for(int i=1;i<m;i++){ scanf("%d",&x); ans=min(ans,x); } printf("%d",ans);return 0; } for(int i=1;i<=n;i++){ for(int j=1;j<m;j++){ scanf("%d",&x); if(i==1)add(S,2*j,x); else if(i<n)add((i-2)*H+2*j-1,(i-1)*H+2*j,x); else add((i-2)*H+2*j-1,T,x); } } for(int i=1;i<n;i++){ for(int j=1;j<=m;j++){ scanf("%d",&x); if(j==1)add((i-1)*H+1,T,x); else if(j<m)add((i-1)*H+2*j-1,(i-1)*H+2*j-2,x); else add(S,(i-1)*H+2*j-2,x); } } for(int i=1;i<n;i++){ for(int j=1;j<m;j++){ scanf("%d",&x); add((i-1)*H+2*j,(i-1)*H+2*j-1,x); } } memset(dis,0x3f,sizeof(dis)); dis[S]=0; q.push(make_pair(dis[S],S)); while(!q.empty()){ int x=q.top().second;q.pop(); if(vis[x])continue; vis[x]=1; for(int i=head[x];i;i=nxt[i]){ if(dis[to[i]]>dis[x]+val[i]){ dis[to[i]]=dis[x]+val[i]; q.push(make_pair(-dis[to[i]],to[i])); } } } printf("%d",dis[T]); }