BZOJ1001 [BeiJing2006]狼抓兔子(平面图最小割转最短路)
。。和HDU3870类似。。注意n=1和m=1的情况。
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<algorithm> 5 using namespace std; 6 #define INF (1<<30) 7 #define MAXN 2800000 8 struct Edge{ 9 int v,w,next; 10 }edge[MAXN<<2]; 11 int vs,vt,NV,NE,head[MAXN]; 12 void addEdge(int u,int v,int w){ 13 edge[NE].v=v; edge[NE].w=w; edge[NE].next=head[u]; 14 head[u]=NE++; 15 } 16 struct Node{ 17 int u,d; 18 Node(int _u=0,int _d=0):u(_u),d(_d){} 19 bool operator<(const Node &nd)const{ 20 return nd.d<d; 21 } 22 }; 23 int d[MAXN]; 24 bool vis[MAXN]; 25 int dijkstra(){ 26 for(int i=0; i<NV; ++i){ 27 d[i]=INF; vis[i]=0; 28 } 29 d[vs]=0; 30 priority_queue<Node> que; 31 que.push(Node(vs,0)); 32 while(!que.empty()){ 33 Node nd=que.top(); que.pop(); 34 if(nd.u==vt) return nd.d; 35 if(vis[nd.u]) continue; 36 vis[nd.u]=1; 37 for(int i=head[nd.u]; i!=-1; i=edge[i].next){ 38 int v=edge[i].v; 39 if(vis[v]) continue; 40 if(d[v]>d[nd.u]+edge[i].w){ 41 d[v]=d[nd.u]+edge[i].w; 42 que.push(Node(v,d[v])); 43 } 44 } 45 } 46 return INF; 47 } 48 int main(){ 49 int n,m,a; 50 scanf("%d%d",&n,&m); 51 if(n==1 && m==1){ 52 puts("0"); 53 return 0; 54 } 55 vs=(n-1)*(m-1)*2; vt=vs+1; NV=vt+1; NE=0; 56 memset(head,-1,sizeof(head)); 57 int mm=INF; 58 for(int i=0; i<n; ++i){ 59 for(int j=0; j<m-1; ++j){ 60 scanf("%d",&a); 61 mm=min(mm,a); 62 if(i==0) addEdge(i*(m-1)+j,vt,a); 63 if(i==n-1) addEdge(vs,(i-1)*(m-1)+j+(n-1)*(m-1),a); 64 if(i!=0 && i!=n-1){ 65 addEdge(i*(m-1)+j,(i-1)*(m-1)+j+(n-1)*(m-1),a); 66 addEdge((i-1)*(m-1)+j+(n-1)*(m-1),i*(m-1)+j,a); 67 } 68 } 69 } 70 for(int i=0; i<n-1; ++i){ 71 for(int j=0; j<m; ++j){ 72 scanf("%d",&a); 73 mm=min(mm,a); 74 if(j==0) addEdge(vs,i*(m-1)+j+(n-1)*(m-1),a); 75 if(j==m-1) addEdge(i*(m-1)+j-1,vt,a); 76 if(j!=0 && j!=m-1){ 77 addEdge(i*(m-1)+j+(n-1)*(m-1),i*(m-1)+j-1,a); 78 addEdge(i*(m-1)+j-1,i*(m-1)+j+(n-1)*(m-1),a); 79 } 80 } 81 } 82 for(int i=0; i<n-1; ++i){ 83 for(int j=0; j<m-1; ++j){ 84 scanf("%d",&a); 85 mm=min(mm,a); 86 addEdge(i*(m-1)+j,i*(m-1)+j+(n-1)*(m-1),a); 87 addEdge(i*(m-1)+j+(n-1)*(m-1),i*(m-1)+j,a); 88 } 89 } 90 if(n==1 || m==1) printf("%d",mm); 91 else printf("%d",dijkstra()); 92 return 0; 93 }