Topic Links:
https://www.luogu.org/problem/show?pid=3381
Main topic:
Maximum flow and cost flow
Topic Ideas:
Minimum cost maximum flow template questions, notes are marked in the template.
Code:
#include <bits/stdc++.h> using namespace std;
int n,m; int s,t; S is the source point T is the sink-point const int MAXN = 5010; The maximum value of the point const int MAXM = 100100; The maximum value of the edge of the const int INF = 0x7fffffff;
INF open error may be t struct edge{int to,next,cap,flow;
int cost;
} EDGE[MAXM];
int head[maxn],tol;
int PRE[MAXN];
int DIS[MAXN];
BOOL VIS[MAXN];
int N; void init ()//Do not forget init () {N = n+10;
Do not open too large may be t tol = 0;
memset (head,-1,sizeof (head)); s=0;//Source Point Super Source Point can set its own//t=n+1; Meeting point, I'm driving here. N+10 The result is timed out, the unknown Li Super meeting point can set its own} void Addedge (int u,int v,int cap,double cost)//build edge, cap is capacity cost is expense {edge
[tol].to = v;
Edge[tol].cap = cap;
Edge[tol].cost = Cost;
Edge[tol].flow = 0;
Edge[tol].next = Head[u];
Head[u] = tol++;
edge[tol].to = u;
Edge[tol].cap = 0;
Edge[tol].cost =-cost;
Edge[tol].flow = 0;
Edge[tol].next = Head[v];
HEAD[V] = tol++; } bool SPFA (int s,int t)//s is the source point T is the sink point {QUEUE≪int>q;
for (int i = 0; i < N; i++) {dis[i] = INF;
Vis[i] = false;
Pre[i] =-1;
} Dis[s] = 0;
Vis[s] = true;
Q.push (s);
while (!q.empty ()) {int u = q.front ();
Q.pop ();
Vis[u] = false;
for (int i = head[u]; i =-1; i = edge[i].next) {int v = edge[i].to;
if (Edge[i].cap > Edge[i].flow && dis[v]-dis[u]-edge[i].cost>0) {//floating-point number plus precision judgment, otherwise it will T
DIS[V] = Dis[u] + edge[i].cost;
PRE[V] = i;
if (!vis[v]) {Vis[v] = true;
Q.push (v);
}}}} if (pre[t] = = 1) return false;
else return true;
} int mincostmaxflow (int s,int t,int &cost) {//cost returns the minimum charge int flow = 0;//flow returns the maximum stream cost = 0; while (SPFA (s,t)) {int Min = INF;
for (int i = pre[t]; i =-1; i = pre[edge[i^1].to]) {if (Min > Edge[i].cap-edge[i].flow)
Min = Edge[i].cap-edge[i].flow;
} for (int i = pre[t]; i =-1; i = pre[edge[i^1].to]) {edge[i].flow + = Min;
Edge[i^1].flow = Min;
Cost + = Edge[i].cost * Min;
} flow + = Min; } return flow;
Find out Max stream} int main () {scanf ("%d%d%d%d", &n,&m,&s,&t);
Init ();//Do not forget the init for (int i=1;i<=m;i++) {int ui,vi,wi,fi; scanf ("%d%d%d%d", &ui,&vi,&wi,&fi);//For the maximum fee, ****************** only need to take the opposite number of costs ********************
* Addedge (UI,VI,WI,FI);
} int Ans=0;//ans is the minimum cost printf ("%d", Mincostmaxflow (S,t,ans));
printf ("%d\n", ans);
return 0; }