Problem Portal
Portal1: Luogu
Description
For example, give a network diagram, its source and sink points, and find out the maximum flow of its network.
Input
The first line contains four positive integers \ (N,M,S,T \), which respectively represent the number of points, the number of directed edges, the source point serial number and the sink point serial number.
Next, each line of \ (M \) contains three positive integers \ (u_i,v_i,w_i \), indicating that the directed edge of \ (I \) starts from \ (w_i \) to \ (v_i \), and the edge weight is \ (w_i \) (that is, the maximum flow of the edge is \ (w_i \).
Output
A row containing a positive integer is the maximum flow of the network.
Sample Input
4 5 4 3 4 2 30 4 3 20 2 3 20 2 1 30 1 3 40
Sample Output
50
Hint
Data size:
Data for \ (30 \% \): \ (N \leq 10,M \leq 25 \);
Data for \ (70 \% \): \ (N \leq 200,M \leq 1000 \);
Data for \ (100 \% \): \ (N \leq 10000,M \leq 100000 \).
Example description:
There are \ (3 \) paths in the topic:
\(4 \to 2 \to 3 \), the route can pass the traffic of \ (20 \)
\(4 \to 3 \), traffic through \ (20 \)
\(4 \to 2 \to 1 \to 3 \), traffic that can pass through \ (10 \) (traffic that has consumed \ (20 \) before side \ (4 \to 2 \)
Therefore, the total flow is \ (20 + 20 + 10 = 50 \), and the output is \ (50 \).
Solution
Template problem, find the maximum flow.
Code
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<cmath> #include<queue> using namespace std; const int INF=0x3f3f3f3f, MAXN=10005, MAXM=200005; int n, m, s, t, u, v, val, cnt, head[MAXN], dis[MAXN], pre[MAXN]; queue<int> Q; struct node { int u, v, val, flow, nxt; } edge[MAXM]; inline void addedge(int u, int v, int w) {//Forward star map edge[++cnt].u=u; edge[cnt].v=v; edge[cnt].val=w; edge[cnt].nxt=head[u]; head[u]=cnt; } inline bool Emonds_Karp() { memset(pre, 0, sizeof(pre)); memset(dis, 0, sizeof(dis));//Initialization dis[s]=INF; pre[s]=0; Q.push(s); while(!Q.empty()) {//Similar to SPFA int x=Q.front(); Q.pop(); for (int i=head[x]; i; i=edge[i].nxt) { int v=edge[i].v; if (!dis[v] && edge[i].val>edge[i].flow) { Q.push(v); dis[v]=min(dis[x], edge[i].val-edge[i].flow); pre[v]=i; } if (dis[t]) break; } } return dis[t]; } int main() { scanf("%d%d%d%d",&n, &m, &s, &t); cnt=1; for(int i=1; i<=m; i++) { scanf("%d%d%d",&u, &v, &val); addedge(u, v, val); addedge(v, u, 0);//Forward star map } int ans=0; while (Emonds_Karp()) {//Emonds Karp algorithm for (int i=t; i!=s; i=edge[pre[i]].u) { edge[pre[i]].flow+=dis[t]; edge[pre[i] xor 1].val-=dis[t]; } ans+=dis[t]; } printf("%d\n",ans); return 0; }
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<cmath> #include<queue> using namespace std; const int INF=0x3f3f3f3f, MAXN=10005, MAXM=200005; struct node { int nxt, to, val; } edge[MAXM]; queue<int> Q; int n, m, s, t, u, v, cnt, val, dis[MAXN], head[MAXN]; inline void addedge(int u, int v, int w) {//Forward star map edge[++cnt].val=w; edge[cnt].to=v; edge[cnt].nxt=head[u]; head[u]=cnt; } inline bool bfs() { memset(dis, -1, sizeof(dis)); dis[s]=0; Q.push(s); while (!Q.empty()) { int x=Q.front(); Q.pop(); for (int i=head[x]; ~i; i=edge[i].nxt) { int v=edge[i].to; if (edge[i].val && dis[v]==-1) { dis[v]=dis[x]+1; Q.push(v); } } } if (~dis[t]) return 1; return 0; } inline int dfs(int u, int flow) { if (u==t) return flow; int ret=flow; for (int i=head[u]; ~i; i=edge[i].nxt) { if (ret<=0) break; int v=edge[i].to; if (edge[i].val && dis[v]==dis[u]+1) { int x=dfs(v, min(edge[i].val, ret)); ret-=x; edge[i].val-=x; edge[i xor 1].val+=x; } } return flow-ret; } inline int Dinic() {//Dinic algorithm int ret=0; while (bfs()) ret+=dfs(s, INF); return ret; } int main() { scanf("%d%d%d%d",&n, &m, &s, &t); memset(head, -1, sizeof(head)); cnt=1; for (int i=1; i<=m; i++) { scanf("%d%d%d",&u, &v, &val); addedge(u, v, val); addedge(v, u, 0);//bilateral } printf("%d\n",Dinic()); return 0; }
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<cmath> #include<queue> using namespace std; const int INF=0x3f3f3f3f, MAXN=10005, MAXM=200005; queue<int> Q; int n, m, s, t, u, v, val, cnt, ans, head[MAXN], head1[MAXN], deep[MAXN], pre[MAXN], a[MAXN]; struct node { int v, w, nxt; } edge[MAXM]; inline void addedge(int u, int v, int w) {//Forward star map edge[cnt].v=v; edge[cnt].w=w; edge[cnt].nxt=head[u]; head[u]=cnt++; } inline void bfs(int t) { for (int i=1; i<=n; i++) head1[i]=head[i]; for (int i=1; i<=n; i++) deep[i]=n; deep[t]=0; Q.push(t); while (!Q.empty()) { int u=Q.front(); Q.pop(); for (int i=head[u]; ~i; i=edge[i].nxt) if (deep[edge[i].v]==n && edge[i^1].w) { deep[edge[i].v]=deep[u]+1; Q.push(edge[i].v); } } } int calc(int s,int t) {//Calculation int ans=INF, u=t; while (u!=s) { ans=min (ans,edge[pre[u]].w); u=edge[pre[u] xor 1].v; } u=t; while (u!=s) { edge[pre[u]].w-=ans; edge[pre[u] xor 1].w+=ans; u=edge[pre[u] xor 1].v; } return ans; } inline void ISAP(int s, int t) {//ISAP algorithm int u=s; bfs(t); for (int i=1; i<=n; i++) a[deep[i]]++; while (deep[s]<n) { if (u==t) { ans+=calc(s, t); u=s; } bool flag=0; for (int &i=head1[u]; ~i; i=edge[i].nxt) if (deep[u]==deep[edge[i].v]+1 && edge[i].w) { flag=1; u=edge[i].v; pre[edge[i].v]=i; break; } if (!flag) { int Min=n-1; for (int i=head[u]; ~i; i=edge[i].nxt) if (edge[i].w) Min=min(Min, deep[edge[i].v]); if ((--a[deep[u]])==0) break; a[deep[u]=Min+1]++; head1[u]=head[u]; if (u!=s) u=edge[pre[u] xor 1].v; } } } int main() { memset(head, -1, sizeof (head)); scanf("%d%d%d%d",&n, &m, &s, &t); for (int i=1; i<=m; i++) { scanf("%d%d%d",&u, &v, &val); addedge(u, v, val); addedge(v, u, 0);//bilateral } ISAP(s, t); printf ("%d\n",ans); return 0; }