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 }

 

posted @ 2016-05-05 19:26  WABoss  阅读(274)  评论(0编辑  收藏  举报