Luogu 3376 模板网络最大流
Posted caterpillor
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luogu 3376 模板网络最大流相关的知识,希望对你有一定的参考价值。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<algorithm> #include<queue> #define inf 0x3f3f3f3f using namespace std; int hd[10005],cnt=-1,d[10005],vis[10005]; struct Edge{ int to,vl,nxt; }edge[200005]; void add(int u,int v,int w) { cnt++; edge[cnt].to =v; edge[cnt].nxt=hd[u]; edge[cnt].vl=w; hd[u]=cnt; } queue<int> q; int s,t; int bfs() { memset(d,0,sizeof d); memset(vis,0,sizeof vis); while(q.size()) q.pop() ;//这个不写会T d[s]=1;vis[s]=1; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); for(int i=hd[u];i!=-1;i=edge[i].nxt)//边是从零开始的,因此这里可以不能是i>0 //同一条边还有容量可以流怎么办,边已经遍历完 { int v=edge[i].to; if(!vis[v] && edge[i].vl>0) { vis[v]=1; d[v]=d[u]+1; q.push(v); if(v==t)return 1; } } } return 0; } int dinic(int u,int res)// { if(u==t) return res; int sum=0; for(int i=hd[u];i!=-1;i=edge[i].nxt) { int v=edge[i].to; if(d[u]+1==d[v] && edge[i].vl>0 && res>0)// { int k=dinic(v,min(res,edge[i].vl)); //剩余流量及该路径容量的最小值 edge[i].vl-=k; edge[i^1].vl+=k; res-=k; sum+=k; } } return sum; } int n,m,u,v,w,flow,mxflow; int main() { scanf("%d%d%d%d",&n,&m,&s,&t); memset(hd,-1,sizeof hd); for(int i=1;i<=m;i++) { scanf("%d%d%d",&u,&v,&w); add(u,v,w); add(v,u,0); } bfs(); for(int i=1;i<=n;i++) cout<<d[i]<<" "; cout<<endl; while(bfs()){ while(flow=dinic(s,inf)) mxflow+=flow; } cout<<mxflow<<endl; }
优化:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<algorithm> #include<queue> #define inf 0x3f3f3f3f using namespace std; int hd[10005],cnt=-1,d[10005],vis[10005],cur[10005]; struct Edge{ int to,vl,nxt; }edge[200005]; void add(int u,int v,int w) { cnt++; edge[cnt].to =v; edge[cnt].nxt=hd[u]; edge[cnt].vl=w; hd[u]=cnt; } queue<int> q; int s,t; int bfs() { memset(d,0,sizeof d); memset(vis,0,sizeof vis); while(q.size()) q.pop() ;//这个不写会T d[s]=1;vis[s]=1; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); for(int i=hd[u];i!=-1;i=edge[i].nxt)//边是从零开始的,因此这里可以不能是i>0 //同一条边还有容量可以流怎么办,边已经遍历完 { int v=edge[i].to; if(!vis[v] && edge[i].vl>0) { vis[v]=1; d[v]=d[u]+1; q.push(v); if(v==t)return 1; } } } return 0; } int dinic(int u,int res)// { if(u==t) return res; int sum=0; for(int i=cur[u];i!=-1;i=edge[i].nxt) { cur[u]=i;//当前弧优化,不符合的通道就不再判断了 int v=edge[i].to; if(d[u]+1==d[v] && edge[i].vl>0 && res>0)// { int k=dinic(v,min(res,edge[i].vl)); //剩余流量及该路径容量的最小值 if(!k) { d[v]=0;//去掉增广完的点 break; } edge[i].vl-=k; edge[i^1].vl+=k; res-=k; sum+=k; } } return sum; } int n,m,u,v,w,flow,mxflow; int main() { scanf("%d%d%d%d",&n,&m,&s,&t); memset(hd,-1,sizeof hd); for(int i=1;i<=m;i++) { scanf("%d%d%d",&u,&v,&w); add(u,v,w); add(v,u,0); } // for(int i=1;i<=n;i++) // cout<<d[i]<<" "; // cout<<endl; while(bfs()){ while(flow=dinic(s,inf)) mxflow+=flow; } cout<<mxflow<<endl; }
以上是关于Luogu 3376 模板网络最大流的主要内容,如果未能解决你的问题,请参考以下文章