bzoj 1001 狼抓兔子

题目大意:

一个网格图,路径样式如下

求最小割

思路:

数据太大,不能直接最小割,而这个图是个平面图(显而易见)

于是我们可以对偶图

所谓对偶图,就是把平面图的每个块看做是一个点,如图:

 

然后spfa跑一遍最短路就好了

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<set>
 8 #include<map>
 9 #include<vector>
10 #include<stack>
11 #include<queue>
12 #define ll long long
13 #define inf 2147383611
14 #define MAXN 1001001
15 #define MOD
16 using namespace std;
17 inline int read()
18 {
19     int x=0,f=1;
20     char ch;ch=getchar();
21     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
22     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
23     return x*f;
24 }
25 int n,m,x,ans,lim;
26 int to[MAXN*6+2010],val[MAXN*6+4010],first[MAXN*2],next[MAXN*6+4010],cnt;
27 int dis[MAXN*2];
28 bool vis[MAXN*2];
29 void add(int u,int v,int d) {next[++cnt]=first[u],first[u]=cnt,val[cnt]=d,to[cnt]=v;}
30 void spfa()
31 {
32     memset(dis,127,sizeof(dis));
33     queue <int> q;
34     q.push(0);dis[0]=0,vis[0]=1;
35     while(!q.empty())
36     {
37         int k=q.front();
38         q.pop();
39         vis[k]=0;
40         for(int i=first[k];i;i=next[i])
41             if(dis[to[i]]>dis[k]+val[i])
42             {
43                 dis[to[i]]=dis[k]+val[i];
44                 if(!vis[to[i]]) {q.push(to[i]);vis[to[i]]=1;}
45             }
46     }
47     printf("%d",dis[lim+1]);
48 }
49 int main()
50 {
51     n=read(),m=read();
52     ans=inf,lim=2*(m-1)*(n-1);
53     if(n==1)
54     {
55         for(int i=1;i<m;i++) {x=read(),ans=min(ans,x);}
56         printf("%d",ans);return 0;
57     }
58     if(m==1)
59     {
60         for(int i=1;i<n;i++) {x=read(),ans=min(ans,x);}
61         printf("%d",ans);return 0;
62     }
63     for(int i=1;i<=n;i++)
64     {
65         for(int j=1;j<m;j++)
66         {
67             x=read();
68             if(i==1) {add(lim+1,j*2,x);add(j*2,lim+1,x);continue;}
69             if(i==n) {add(0,(n-2)*(m-1)*2+j*2-1,x);add((n-2)*(m-1)*2+j*2-1,0,x);continue;}
70             add((i-1)*(m-1)*2+j*2,(i-2)*(m-1)*2+j*2-1,x);add((i-2)*(m-1)*2+j*2-1,(i-1)*(m-1)*2+j*2,x);
71         }
72     }
73     for(int i=1;i<n;i++)
74     {
75         for(int j=1;j<=m;j++)
76         {
77             x=read();
78             if(j==1) {add(0,(m-1)*(i-1)*2+1,x);add(2*(m-1)*(i-1)+1,0,x);continue;}
79             if(j==m) {add(lim+1,i*(m-1)*2,x);add(i*(m-1)*2,lim+1,x);continue;}
80             add((i-1)*(m-1)*2+2*(j-1),(i-1)*(m-1)*2+2*j-1,x);add((i-1)*(m-1)*2+2*j-1,(i-1)*(m-1)*2+2*(j-1),x);
81         }
82     }
83     for(int i=1;i<n;i++)
84     {
85         for(int j=1;j<m;j++)
86         {
87             x=read();
88             add((i-1)*(m-1)*2+2*j,(i-1)*(m-1)*2+2*j-1,x);add((i-1)*(m-1)*2+2*j-1,(i-1)*(m-1)*2+2*j,x);
89         }
90     }
91     spfa();
92 }
View Code
posted @ 2017-10-09 20:54  jack_yyc  阅读(276)  评论(0编辑  收藏  举报