P3376 【模板】網路最大流
阿新 • • 發佈:2018-12-26
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<cmath> #include<bitset> #define mme(a,b) memset((a),(b),sizeof((a))) #define precision(x,d) cout<<fixed<<setprecision(d)<<x<<"\n" #define iis std::ios::sync_with_stdio(false) using namespace std; typedef long long LL; const int INF = 0x3f3f3f3f; const int N = 1e5+5; int n,m; const int MAXN = 1e4+105; const int MAXE = 4e5+7; struct lp { int v,nex; int cap,flow; } cw[MAXE]; int vs,vt,NE,NV; int head[MAXN],pre[MAXN],cur[MAXN],level[MAXN],gap[MAXN]; inline void add_edge(int u,int v,int cap){ cw[NE].v = v;cw[NE].cap = cap;cw[NE].flow = 0;cw[NE].nex = head[u]; head[u] = NE++; cur[u] = head[u]; cw[NE].v = u;cw[NE].cap = 0;cw[NE].flow = 0;cw[NE].nex = head[v]; head[v] = NE++; cur[v] = head[v]; } inline void bfs(int vt){ memset(level,-1,sizeof(level)); memset(gap,0,sizeof(gap)); level[vt]=0; gap[level[vt]]++; queue<int>que; que.push(vt); while(!que.empty()) { int u=que.front(); que.pop(); for(int i=head[u]; i!=-1; i=cw[i].nex) { int v=cw[i].v; if(level[v]!=-1)continue; level[v]=level[u]+1; gap[level[v]]++; que.push(v); } } } int SAP(int vs,int vt){ bfs(vt); memset(pre,-1,sizeof(pre)); //for(int i=0;i<=n;++i)cur[i]=head[i]; int u=pre[vs]=vs,flow=0,aug=INF; gap[0]=NV; while(level[vs]<NV) { bool flag=false; for(int &i=cur[u]; i!=-1; i=cw[i].nex) { int v=cw[i].v; if(cw[i].cap>cw[i].flow&&level[u]==level[v]+1) { flag=true; pre[v]=u; u=v; // aug=(aug==-1?cw[i].cap:min(aug,cw[i].cap)); aug=min(aug,cw[i].cap-cw[i].flow ); if(v==vt) { flow+=aug; for(u=pre[v]; v!=vs; v=u,u=pre[u]) { cw[cur[u]].flow+=aug; cw[cur[u]^1].flow-=aug; } // aug=-1; aug=INF; } break; } } if(flag)continue; int minlevel=NV; for(int i=head[u]; i!=-1; i=cw[i].nex) { int v=cw[i].v; if(cw[i].cap>cw[i].flow&&level[v]<minlevel) { minlevel=level[v]; cur[u]=i; } } if(--gap[level[u]]==0)break; level[u]=minlevel+1; gap[level[u]]++; u=pre[u]; } return flow; } void init(){ NE=0;NV=n; //vs=1;vt=n; memset(head,-1,sizeof(head)); memset(cur,-1,sizeof(cur)); } int main(){ int u,v,w; scanf("%d%d%d%d",&n,&m,&vs,&vt); init(); for(int i=1; i<=m; i++) { scanf("%d%d%d",&u,&v,&w); add_edge(u,v,w); } printf("%d\n",SAP(vs,vt)); return 0; }
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<cmath> #include<bitset> #define mme(a,b) memset((a),(b),sizeof((a))) #define precision(x,d) cout<<fixed<<setprecision(d)<<x<<"\n" #define iis std::ios::sync_with_stdio(false) using namespace std; typedef long long LL; const int INF = 0x3f3f3f3f; const int MXN = 1e4+7; const int MXE = 4e5+7; int vs, vt; struct DINIC{ int tot,vt,vs; int d[MXN],head[MXN]; struct lp{ int v,w,nex; }cw[MXE]; void add_edge(int a,int b,int c){ cw[++tot].v=b;cw[tot].nex=head[a],cw[tot].w=c; head[a]=tot; cw[++tot].v=a;cw[tot].nex=head[b],cw[tot].w=0; head[b]=tot; } bool bfs(){ memset(d,-1,sizeof(d)); queue<int>Q; Q.push(vt);d[vt]=0; while(!Q.empty()){ int u=Q.front(); Q.pop(); for(int i=head[u];i!=-1;i=cw[i].nex){ int v=cw[i].v; if(cw[i^1].w&&d[v]==-1){ d[v]=d[u]+1; Q.push(v); } } } return d[vs]!=-1; } /*int dfs(int x,int low){ if(x==vt||low==0)return low; int flow=0,used=0; for(int i=head[x];i!=-1;i=cw[i].nex){ int v=cw[i].to; if(cw[i].w&&d[v]+1==d[x]&&(used=dfs(v,min(low,cw[i].w)))>0){ //used=dfs(v,min(low,cw[i].w)); if(!used)continue; flow+=used,low-=used; cw[i].w-=used;cw[i^1].w+=used; if(!low)break; } } if(!flow)d[x]=-1; return flow; }*/ int dfs(int x,int f){ if(x==vt||f==0) return f; int use=0,w; for(int i=head[x];i!=-1;i=cw[i].nex){ int to=cw[i].v; if(d[to]==d[x]-1 && cw[i].w){ w=dfs(to,min(cw[i].w,f-use)); cw[i].w-=w,cw[i^1].w+=w; use+=w; if(use==f) return f; } } if(!use)d[x]=-1; return use; } void init(int st,int ed){ tot=-1; memset(head,-1,sizeof(head)); vs=st;vt=ed; } int max_flow(){ int ans=0; while(bfs())ans+=dfs(vs,INF); return ans; } }dinic; int main(){ int u,v,w,n,m; scanf("%d%d%d%d",&n,&m,&vs,&vt); dinic.init(vs,vt); for(int i=1; i<=m; i++) { scanf("%d%d%d",&u,&v,&w); dinic.add_edge(u,v,w); } printf("%d\n",dinic.max_flow()); return 0; }
#include<iostream> #include<algorithm> #include<queue> #include<vector> #include<stack> #include <cstdio> #include <cstring> using namespace std; const int inf = 0x3fffffff; template <int N, int M> struct Isap{ int top; int d[N], pre[N], cur[N], gap[N]; struct Vertex { int head; } V[N]; struct Edge { int v, next; int c, f; } E[M]; void init() { memset(V, -1, sizeof(V)); top = 0; } void add_edge(int u, int v, int c) { E[top].v = v; E[top].c = c; E[top].f = 0; E[top].next = V[u].head; V[u].head = top++; } void add(int u, int v, int c) { add_edge(u, v, c); add_edge(v, u, 0); } void set_d(int t) { queue<int> Q; memset(d, -1, sizeof(d)); memset(gap, 0, sizeof(gap)); d[t] = 0; Q.push(t); while (!Q.empty()) { int v = Q.front(); Q.pop(); ++gap[d[v]]; for (int i = V[v].head; ~i; i = E[i].next) { int u = E[i].v; if (d[u] == -1) { d[u] = d[v] + 1; Q.push(u); } } } } int sap(int s, int t, int num) { set_d(t); int ans = 0, u = s; int flow = inf; memcpy(cur, V, sizeof(V)); while (d[s] < num) { int &i = cur[u]; for (; ~i; i = E[i].next) { int v = E[i].v; if (E[i].c > E[i].f && d[u] == d[v] + 1) { u = v; pre[v] = i; flow = min(flow, E[i].c - E[i].f); if (u == t) { while (u != s) { int j = pre[u]; E[j].f += flow; E[j ^ 1].f -= flow; u = E[j ^ 1].v; } ans += flow; flow = inf; } break; } } if (i == -1) { if (--gap[d[u]] == 0) break; int dmin = num - 1; cur[u] = V[u].head; for (int j = V[u].head; ~j; j = E[j].next) if (E[j].c > E[j].f) dmin = min(dmin, d[E[j].v]); d[u] = dmin + 1; ++gap[d[u]]; if (u != s) u = E[pre[u] ^ 1].v; } } return ans; } }; Isap<200005, 400005> Sap; int tux[100001], tuy[100001],st,zt; int main(){ int n, m; scanf("%d%d%d%d", &n, &m, &st, &zt); int q, w, e; Sap.init(); for (int a = 1; a <= m; a++){ scanf("%d%d%d", &q, &w, &e); Sap.add(q, w, e); } printf("%d\n",Sap.sap(st, zt, 9 * m + 2)); return 0; }