bzoj1001最小割

听说最大流过不去???

dinic果然神了,1000,000的点都能过(主要是比较稀疏)

 1 #include <cstdio>
 2 #define INF 9223372036854775807
 3 int n,m,x,y,z,p,M=1;long long ans=0;
 4 int d[1000005],l[1000005],fir[1000005],nex[6000005],to[6000005],wei[6000005];
 5 int min(long long a,long long b){if(a<b) return a;else return b;}
 6 void add(int x,int y,int z){to[++M]=y;wei[M]=z;nex[M]=fir[x];fir[x]=M;
 7                             to[++M]=x;wei[M]=z;nex[M]=fir[y];fir[y]=M;}
 8 long long dfs(int now,long long flow)
 9 {
10     if(now==n*m)
11         return flow;
12     long long used=0;
13     for(int i=fir[now];i;i=nex[i])
14         if(d[to[i]]==d[now]+1 && wei[i])
15             {
16                 int fl=dfs(to[i],min(flow-used,wei[i]));
17                 wei[i]-=fl,wei[i^1]+=fl;
18                 used+=fl;
19                 if(used==flow)
20                     return flow;
21             }
22 //    if(!used) d[now]=-1;这句必写,否则T
23     return used;
24 }
25 bool bfs()
26 {
27     int h=0,t=1;
28     l[1]=1;d[1]=0;
29     for(int i=2;i<=n*m;i++) d[i]=-1;
30     while(h<t)
31         for(int i=fir[l[++h]];i;i=nex[i])
32         if(wei[i] && (d[to[i]]==-1))
33             l[++t]=to[i],d[l[t]]=d[l[h]]+1;
34     return d[n*m]+1;
35 }
36 int main()
37 {
38     scanf("%d%d",&n,&m);
39     for(int i=1;i<=n;i++)
40         for(int j=1;j<m;j++)
41             scanf("%d",&p),add((i-1)*m+j,(i-1)*m+j+1,p);
42     for(int i=1;i<n;i++)
43         for(int j=1;j<=m;j++)
44             scanf("%d",&p),add((i-1)*m+j,i*m+j,p);
45     for(int i=1;i<n;i++)
46         for(int j=1;j<m;j++)
47             scanf("%d",&p),add((i-1)*m+j,i*m+j+1,p);
48     while(bfs()) ans+=dfs(1,INF);
49     printf("%lld\n",ans);
50     return 0;
51 }

不要管longlong,现在打网络流就会想起以前忘记longlong调一晚上的痛苦

posted @ 2016-09-11 20:59  汪立超  阅读(488)  评论(3编辑  收藏  举报