网络流——增广路算法(dinic)模板 [BeiJing2006]狼抓兔子

 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<cstdio>
 6 #include<queue>
 7 using namespace std;
 8 struct data
 9 {
10     int from,to,next,cup;
11     data(){from=-1,to=-1,next=-1,cup=-1;}
12 }e[6000001];
13 int cnt=0,head[1000001];
14 int dis[1000001];
15 bool vis[1000001];
16 void add(int u,int v,int w)
17 {e[cnt].from=u,e[cnt].to=v,e[cnt].next=head[u],head[u]=cnt,e[cnt].cup=w;cnt++;}
18 int s,t;
19 bool bfs()
20 {
21     memset(dis,-1,sizeof(dis));
22     int f=2147483647;
23     queue<int> q;
24     q.push(s);
25     dis[s]=0;
26     while(!q.empty())
27     {
28         int n=q.front();
29         q.pop();
30         for(int i=head[n];i>=0;i=e[i].next)
31         {
32             if(dis[e[i].to]==-1&&e[i].cup>0)
33             {
34                 dis[e[i].to]=dis[n]+1;
35                 q.push(e[i].to);
36             }
37         }
38     }
39     return dis[t]!=-1;
40 }
41 int dfs(int n,int a)
42 {
43     
44     if(n==t||a==0) return a;
45     int flow=0,f;
46     for(int i=head[n];i>=0;i=e[i].next)
47     {
48         if(dis[e[i].to]==dis[n]+1&&e[i].cup>0)
49         {
50             f=dfs(e[i].to,min(a,e[i].cup));
51             e[i].cup-=f;
52             e[i^1].cup+=f;
53             flow+=f;
54             a-=f;
55             if(a==0) break;
56         }
57     }
58     if(!flow) dis[n]=-1;
59     return flow;
60 }
61 int dinic()
62 {
63     int sum=0;
64     while(bfs()) sum+=dfs(s,2147483647);
65     return sum;
66 }
67 int main()
68 {
69     memset(head,-1,sizeof(head));
70     int n,m;
71     scanf("%d%d",&n,&m);
72     int x;
73     for(int i=1;i<=n;i++)
74         for(int j=1;j<m;j++)
75         {
76             scanf("%d",&x);
77             add(m*(i-1)+j,m*(i-1)+j+1,x);
78             add(m*(i-1)+j+1,m*(i-1)+j,x);
79         }
80     for(int i=1;i<n;i++)
81         for(int j=1;j<=m;j++)
82         {
83             scanf("%d",&x);
84             add(m*(i-1)+j,m*(i)+j,x);
85             add(m*(i)+j,m*(i-1)+j,x);
86         }
87     for(int i=1;i<n;i++)
88         for(int j=1;j<m;j++)
89         {
90             scanf("%d",&x);
91             add(m*(i-1)+j,m*(i)+j+1,x);
92             add(m*(i)+j+1,m*(i-1)+j,x);
93         }
94     s=1,t=m*n;
95     printf("%d\n",dinic());
96 }
View Code

 

posted @ 2016-06-18 12:54  wls001  阅读(167)  评论(0编辑  收藏  举报