bzoj1001: [BeiJing2006]狼抓兔子(初识是你最小割)

1001: [BeiJing2006]狼抓兔子

题目:传送门

 

 

题解:

   听说这题当初是大难题...可惜当年没有网络流hahahha

   现在用网络流的思想就很容易解决了嘛

   给什么连什么,注意是双向边,然后跑最大流...AC

 

代码:

  

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<algorithm>
 6 #define N 1100000
 7 using namespace std;
 8 struct node
 9 {
10     int x,y,c,next,other;
11 }a[6110000];int len,last[3110000];
12 int n,m,head,tail,st,ed;
13 void ins(int x,int y,int c)
14 {
15     int k1,k2;
16     len++;k1=len;
17     a[len].x=x;a[len].y=y;a[len].c=c;
18     a[len].next=last[x];last[x]=len;
19     
20     len++;k2=len;
21     a[len].x=y;a[len].y=x;a[len].c=c;
22     a[len].next=last[y];last[y]=len;
23     
24     a[k1].other=k2;
25     a[k2].other=k1;
26 }
27 int list[3110000],h[3110000];
28 bool bt_h()
29 {
30     memset(h,0,sizeof(h));h[st]=1;
31     list[1]=st;head=1;tail=2;
32     while(head!=tail)
33     {
34         int x=list[head];
35         for(int k=last[x];k;k=a[k].next)
36         {
37             int y=a[k].y;
38             if(h[y]==0 && a[k].c>0)
39             {
40                 h[y]=h[x]+1;
41                 list[tail++]=y;
42             }
43         }
44         head++;
45     }
46     if(h[ed]>0)return true;
47     return false;
48 }
49 int find_flow(int x,int flow)
50 {
51     if(x==ed)return flow;
52     int s=0,t;
53     for(int k=last[x];k;k=a[k].next)
54     {
55         int y=a[k].y;
56         if(h[y]==h[x]+1 && a[k].c>0 && flow>s)
57         {
58             t=find_flow(y,min(a[k].c,flow-s));
59             s+=t;
60             a[k].c-=t;a[a[k].other].c+=t;
61         }
62     }
63     if(s==0)h[x]=0;
64     return s;
65 }
66 int main()
67 {
68     while(scanf("%d%d",&n,&m)!=EOF)
69     {
70         len=0;memset(last,0,sizeof(last));
71         st=1;ed=n*m;
72         for(int i=1;i<=n;i++)
73             for(int j=1;j<m;j++)
74             {
75                 int t;
76                 scanf("%d",&t);
77                 ins((i-1)*m+j,(i-1)*m+j+1,t);
78             }
79         for(int i=1;i<n;i++)
80             for(int j=1;j<=m;j++)
81             {
82                 int t;
83                 scanf("%d",&t);
84                 ins((i-1)*m+j,i*m+j,t);
85             }
86         for(int i=1;i<n;i++)
87             for(int j=1;j<m;j++)
88             {
89                 int t;
90                 scanf("%d",&t);
91                 ins((i-1)*m+j,i*m+j+1,t);
92             }
93         int ans=0;
94         while(bt_h())ans+=find_flow(st,999999999);
95         printf("%d\n",ans);
96     }
97     return 0;
98 }

 

posted @ 2017-12-24 15:23  CHerish_OI  阅读(268)  评论(0编辑  收藏  举报