网络流(模板)

Dicnic算法(最大流/最小割问题)

 1 ///网络流模板
 2 /**
 3 * 题意:n个点,m条有向边,s点为源点,t点为汇点,然后是m条边的u,v,w;求s点到t点的最大流
 4 */
 5 #include<bits/stdc++.h>
 6 using namespace std;
 7 #define ll long long
 8 const int maxn = 100005;
 9 const int maxm = 2000005;
10 const int inf = 0x3f3f3f3f;
11 struct DINIC
12 {
13     struct node
14     {
15         int u,v,w,next;
16     }edge[maxm];
17     int deep[maxn],dl[maxm],fir[maxm];
18     int cnt,aim;
19     void init()
20     {
21         memset(fir,-1,sizeof fir);
22         cnt=0;
23     }
24     void add(int u,int v,int w)
25     {
26         edge[cnt].u=u,edge[cnt].v=v,edge[cnt].w=w;
27         edge[cnt].next=fir[u];
28         fir[u]=cnt++;
29         edge[cnt].u=v,edge[cnt].v=u,edge[cnt].w=0;
30         edge[cnt].next=fir[v];
31         fir[v]=cnt++;
32     }
33     bool bfs(int S,int T)
34     {
35         memset(deep,0,sizeof deep);
36         deep[S]=1;
37         dl[1]=S;
38         int head=0,tail=1;
39         while(head!=tail)
40         {
41             int v=dl[++head];
42             for(int u=fir[v]; ~u; u=edge[u].next)
43             {
44                 if(edge[u].w&&!deep[edge[u].v])
45                 {
46                     deep[edge[u].v]=deep[v]+1;
47                     dl[++tail]=edge[u].v;
48                 }
49             }
50         }
51         return deep[T];
52     }
53     int dfs(int now,int fl)
54     {
55         if(now==aim)
56             return fl;
57         int f=0;
58         for(int u=fir[now]; ~u&&fl; u=edge[u].next)
59         {
60             if(edge[u].w&&deep[edge[u].v]==deep[now]+1)
61             {
62                 int x=dfs(edge[u].v,min(fl,edge[u].w));
63                 edge[u].w-=x;
64                 edge[u^1].w += x;
65                 fl-=x;
66                 f += x;
67             }
68         }
69         if(!f)
70             deep[now]=-2;
71         return f;
72     } int maxflow(int S,int T)
73     {
74         aim= T;
75         int ans=0;
76         while(bfs(S, T))
77             ans += dfs(S, inf);
78         return ans;
79     }
80 } dinic;
81 int main()
82 {
83 //n个点,m条边,求S到T的最大流/最小割(dinic算法)
84     int n,m;
85     while(~scanf("%d%d",&n,&m))
86     {
87         int S,T;
88         scanf("%d%d",&S,&T);
89         dinic.init();///初始化
90         for(int i=1; i<=m; i++)
91         {
92             int u,v,w;
93             scanf("%d%d%d",&u,&v,&w);
94             dinic.add(u,v,w);
95         }
96         printf("%d\n",dinic.maxflow(S,T));
97     }
98     return 0;
99 }

 MCMF算法(最小费用流)

  1 ///最小费用最大流
  2 /**
  3 *题意:n个点,m条有向边,s点为起点,t点为汇点,然后输入每条边的u,v,w(边权),f(花费),求其网络最大流以及最大流时的最小费用
  4 */
  5 #include<bits/stdc++.h>
  6 #define max(x,y) ((x) > (y) ? (x) : (y))
  7 #define min(x,y) ((x)<(y)?(x):(y))
  8 #define lowbit(x) ((x)&(-(x)))
  9 #define FAST ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
 10 #define memset0(arr) memset(arr,0,sizeof(arr))
 11 #define il inline
 12 using namespace std;
 13 typedef long long ll;
 14 typedef unsigned long long ull;
 15 typedef pair<int,int>pii;
 16 const int maxn= 1e6;
 17 const int INF=0x7fffffff;
 18 const int mod=1e9+7;
 19 const double eps =1e-7;
 20 const double Pi= acos(-1.0);
 21 il int read_int()
 22 {
 23     char c;
 24     int ret=0,sgn=1;
 25     do
 26     {
 27         c=getchar();
 28     }
 29     while((c<'0'||c>'9')&&c!='-');
 30     if(c=='-')
 31         sgn=-1;
 32     else
 33         ret=c-'0';
 34     while((c=getchar())>='0'&&c<='9')
 35         ret=ret*10+(c-'0');
 36     return sgn*ret;
 37 }
 38 il ll read_ll()
 39 {
 40     char c;
 41     ll ret=0,sgn=1;
 42     do
 43     {
 44         c=getchar();
 45     }
 46     while((c<'0'||c>'9')&&c!='-');
 47     if(c=='-')
 48         sgn= -1;
 49     else
 50         ret=c-'0';
 51     while((c=getchar())>='0'&&c<='9')
 52         ret=ret*10+(c-'0');
 53     return sgn * ret;
 54 }
 55 il ll quick_pow(ll base,ll index)
 56 {
 57     ll res=1;
 58     while(index)
 59     {
 60         if(index&1)
 61             res=res*base%mod;
 62         base=base*base%mod;
 63         index >>= 1;
 64     }
 65     return res;
 66 }
 67 struct edge
 68 {
 69     int to,capacity,cost,rev;
 70     edge() {}
 71     edge(int to,int _capacity,int _cost,int _rev):to(to),capacity(_capacity),cost(_cost),rev(_rev) {}
 72 };
 73 struct Min_Cost_Max_Flow
 74 {
 75     int V,H[maxn+5],dis[maxn+5],PreV[maxn+5],PreE[maxn+5];
 76     vector<edge>G[maxn+5];
 77     void Init(int n)
 78     {
 79         V = n;
 80         for(int i=0; i<=V; ++i)
 81             G[i].clear();
 82     }
 83     void Add_Edge(int from,int to,int cap, int cost)
 84     {
 85         G[from].push_back(edge(to,cap,cost,G[to].size()));
 86         G[to].push_back(edge(from,0,-cost,G[from].size()-1));
 87     }
 88     int Min_cost_max_flow(int s, int t, int f, int& flow)
 89     {
 90         int res=0;
 91         fill(H,H+1+V,0);
 92         while (f)
 93         {
 94             priority_queue<pair<int,int>,vector< pair<int,int> >,greater< pair<int,int> > >q;
 95             fill(dis,dis+1+V,INF);
 96             dis[s]=0;
 97             q.push(pair<int,int>(0,s));
 98             while(!q.empty())
 99             {
100                 pair<int,int>now=q.top();
101                 q.pop();
102                 int v=now.second;
103                 if(dis[v]<now.first)
104                     continue;
105                 for (int i=0; i<G[v].size(); ++i)
106                 {
107                     edge& e=G[v][i];
108                     if(e.capacity>0&&dis[e.to]>dis[v]+e.cost+H[v]-H[e.to])
109                     {
110                         dis[e.to]=dis[v]+e.cost+H[v]-H[e.to];
111                         PreV[e.to]=v;
112                         PreE[e.to]=i;
113                         q.push(pair<int,int>(dis[e.to], e.to));
114                     }
115                 }
116             }
117             if(dis[t]==INF)
118                 break;
119             for(int i=0; i<=V; ++i)
120                 H[i]+= dis[i];
121             int d = f;
122             for(int v=t; v!=s; v=PreV[v])
123                 d=min(d,G[PreV[v]][PreE[v]].capacity);
124             f-=d;
125             flow+=d;
126             res+=d*H[t];
127             for(int v=t; v!=s; v=PreV[v])
128             {
129                 edge& e = G[PreV[v]][PreE[v]];
130                 e.capacity -= d;
131                 G[v][e.rev].capacity += d;
132             }
133         }
134         return res;
135     }
136     int Max_cost_max_flow(int s,int t,int f,int& flow)
137     {
138         int res=0;
139         fill(H,H+1+V,0);
140         while(f)
141         {
142             priority_queue< pair<int,int> >q;
143             fill(dis,dis+1+V,-INF);
144             dis[s]=0;
145             q.push(pair<int,int>(0,s));
146             while(!q.empty())
147             {
148                 pair<int,int>now=q.top();
149                 q.pop();
150                 int v= now.second;
151                 if(dis[v]>now.first)
152                     continue;
153                 for(int i=0; i<G[v].size(); ++i)
154                 {
155                     edge& e=G[v][i];
156                     if(e.capacity>0&&dis[e.to]<dis[v]+e.cost+H[v]-H[e.to])
157                     {
158                         dis[e.to]=dis[v]+e.cost+H[v]-H[e.to];
159                         PreV[e.to]=v;
160                         PreE[e.to]=i;
161                         q.push(pair<int,int>(dis[e.to],e.to));
162                     }
163                 }
164             }
165             if(dis[t]==-INF)
166                 break;
167             for(int i=0; i<=V; ++i)
168                 H[i]+=dis[i];
169             int d=f;
170             for(int v=t; v!=s; v=PreV[v])
171                 d=min(d,G[PreV[v]][PreE[v]].capacity);
172             f-=d;
173             flow+=d;
174             res+=d*H[t];
175             for(int v=t; v!=s; v=PreV[v])
176             {
177                 edge& e=G[PreV[v]][PreE[v]];
178                 e.capacity-=d;
179                 G[v][e.rev].capacity+=d;
180             }
181         }
182         return res;
183     }
184 };
185 int n,k,s1,s2,t,flow,arr[maxn+5];
186 Min_Cost_Max_Flow MCMF;
187 int main()
188 {
189     int n,m,s,t;
190     scanf("%d%d%d%d",&n,&m,&s,&t);
191     MCMF.Init(n);
192     for(int i=1; i<=m; i++)
193     {
194         int u,v,w,c;
195         scanf("%d%d%d%d",&u,&v,&w,&c);
196         MCMF.Add_Edge(u,v,w,c);
197     }
198     flow=0;
199     int ans=MCMF.Min_cost_max_flow(s,t,INF,flow);
200     printf("%d %d\n",flow,ans);
201     return 0;
202 }

 

posted @ 2020-10-11 20:35  杯酒朝阳  阅读(106)  评论(0编辑  收藏  举报