网络流相关模板及结论

一、一些结论 

  1、最大流最小割定理(Maximum Flow, Minimum Cut Theorem):网络的最大流等于最小割

  2、任意一个流都小于等于任意一个割(废话)

  3、(hdu 6214)最小割的割边一定满流,但是满流的边不一定是最小割的割边。(割边必满流,满流不一定是割边)

  4、拆点:目的是让,每个点通过的流量为1。

对于一个网络流图G=(V,E),其中有源点s和汇点t,那么下面三个条件是等价的:
1. 流f是图G的最大流
2. 残留网络Gf不存在增广路
3. 对于G的某一个割(S,T),此时f = C(S,T)

 

 二、模板

  1、Dinic(多路增广+当前弧优化)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int MAXN=1e4+3,MAXM=1e5+3,INF=0x7fffffff;
 4 struct ppp{
 5     int from,to,flow,next;
 6 }edge[MAXM<<1];
 7 int head[MAXN],tot,n,m,s,t,maxflow,vis;
 8 int dep[MAXN],vztd[MAXN],cur[MAXN];//cur µ±Ç°»¡ 
 9 void add(int u,int v,int w)
10 {
11     edge[tot]=(ppp){u,v,w,head[u]};
12     head[u]=tot;
13     tot++;
14 }
15 bool bfs()
16 {
17     for(int i=1;i<=n;i++)    
18         cur[i]=head[i],dep[i]=0x3f3f3f3f,vztd[i]=0;
19     dep[s]=0;
20     queue<int>q;
21     q.push(s);
22     while(!q.empty())
23     {
24         int k=q.front();
25         q.pop();
26         vztd[k]=0;
27         for(int i=head[k];i!=-1;i=edge[i].next)
28         {
29             int d=edge[i].to,lef=edge[i].flow;
30             if(dep[d]>dep[k]+1 and lef)
31             {
32                 dep[d]=dep[k]+1;
33                 if(!vztd[d])
34                 {
35                     q.push(d);
36                     vztd[d]=1;
37                 }
38             }
39         }
40     }
41     if(dep[t]!=0x3f3f3f3f)    return 1;
42     return 0;
43 }
44 int dfs(int u,int flow)
45 {
46     if(u==t)    
47     {
48     //    vis=1;
49         maxflow+=flow;
50         return flow;
51     }
52     int used=0;
53     for(int i=cur[u];i!=-1;i=edge[i].next)
54     {
55         cur[u]=i;
56         int d=edge[i].to;
57         int lef=edge[i].flow;
58         if(lef and dep[d]==dep[u]+1)
59         {
60             int low=dfs(d,min(flow-used,lef));
61             if(low)
62             {
63                 used+=low;
64                 edge[i].flow-=low;
65                 edge[i^1].flow+=low;
66                 if(used==flow)    break;
67             }
68         }
69     }
70     return used;
71 }
72 int dinic()
73 {
74     while(bfs())
75         dfs(s,INF);
76     return maxflow;
77 }
78 int main()
79 {
80     scanf("%d%d%d%d",&n,&m,&s,&t);
81     memset(head,-1,sizeof(head));
82     for(int i=1;i<=m;i++)
83     {
84         int u,v,w;
85         scanf("%d%d%d",&u,&v,&w);
86         add(u,v,w);
87         add(v,u,0);
88     }
89     printf("%d",dinic());
90     return 0;
91 }
View Code

  2、ISAP(加了当前弧怎么还慢了20msQAQ)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int MAX=1e4+3,MAXM=1e5+5,INF=0x7fffffff;
 4 struct ppp{
 5     int to,next,flow;
 6 }edge[MAXM<<1];
 7 int head[MAX],dep[MAX],gap[MAX],cur[MAX];
 8 int n,m,s,t,tot,maxflow=0;
 9 void add(int u,int v,int w)
10 {
11     edge[tot]=(ppp){v,head[u],w};
12     head[u]=tot;
13     tot++;
14 }
15 void bfs()
16 {
17     memset(dep,-1,sizeof(dep));
18     memset(gap,0,sizeof(gap));
19     dep[t]=0;
20     gap[0]=1;
21     queue<int>q;
22     q.push(t);
23     while(!q.empty())
24     {
25         int u=q.front();
26         q.pop();
27         for(int i=head[u];i!=-1;i=edge[i].next)
28         {
29             int v=edge[i].to;
30             if(dep[v]!=-1)    continue;
31             q.push(v);
32             dep[v]=dep[u]+1;
33             gap[dep[v]]++;
34         }
35     }
36     return ;
37 }
38 inline int dfs(int u,int flow)
39 {
40     if(u==t)
41     {
42         maxflow+=flow;
43         return flow;
44     }
45     int used=0;
46     for(int i=cur[u];i!=-1;i=edge[i].next)
47     {
48         cur[u]=i;
49         int v=edge[i].to;
50         if(edge[i].flow and dep[v]+1==dep[u])
51         {
52             int low=dfs(v,min(flow-used,edge[i].flow));
53             if(low)
54             {
55                 edge[i].flow-=low;
56                 edge[i^1].flow+=low;
57                 used+=low;
58             }
59             if(used==flow)    return used;
60         }
61     }
62     gap[dep[u]]--;
63     if(gap[dep[u]]==0)    dep[s]=n+1;
64     dep[u]++;
65     gap[dep[u]]++;
66     return used;
67 }
68 int isap()
69 {
70     bfs();
71     while(dep[s]<n)    
72     {
73         memcpy(cur,head,sizeof(head));
74         dfs(s,INF);
75     }
76     return maxflow;
77 }
78 int main()
79 {
80     scanf("%d%d%d%d",&n,&m,&s,&t);
81     memset(head,-1,sizeof(head));
82     for(int i=1;i<=m;i++)
83     {
84         int u,v,w;
85         scanf("%d%d%d",&u,&v,&w);
86         add(u,v,w);
87         add(v,u,0);
88     }
89     printf("%d",isap());
90     return 0;
91 }
View Code

 

  3、HLPP

-

 

posted @ 2019-02-19 19:46  Member  阅读(184)  评论(0编辑  收藏  举报