P3376 【模板】网络最大流
2017-07-29 15:53
471 查看
题目描述
如题,给出一个网络图,以及其源点和汇点,求出其网络最大流。输入输出格式
输入格式:第一行包含四个正整数N、M、S、T,分别表示点的个数、有向边的个数、源点序号、汇点序号。
接下来M行每行包含三个正整数ui、vi、wi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi)
输出格式:
一行,包含一个正整数,即为该网络的最大流。
输入输出样例
输入样例#1:4 5 4 3 4 2 30 4 3 20 2 3 20 2 1 30 1 3 40
输出样例#1:
50
说明
时空限制:1000ms,128M数据规模:
对于30%的数据:N<=10,M<=25
对于70%的数据:N<=200,M<=1000
对于100%的数据:N<=10000,M<=100000
样例说明:
题目中存在3条路径:
4-->2-->3,该路线可通过20的流量
4-->3,可通过20的流量
4-->2-->1-->3,可通过10的流量(边4-->2之前已经耗费了20的流量)
故流量总计20+20+10=50。输出50。
看了几本教材发现都没有用边表去写网络流的,于是自己琢磨了很长时间,
用的是Dinic算法
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<algorithm> #define lli long long int using namespace std; const int MAXN=300001; const int maxn=0x7fffff; void read(int &n) { char c='+';int x=0;bool flag=0; while(c<'0'||c>'9') {c=getchar();if(c=='-')flag=1;} while(c>='0'&&c<='9') {x=x*10+c-48;c=getchar();} flag==1?n=-x:n=x; } struct node { int u,v,flow,cap,nxt; }edge[MAXN]; int head[MAXN]; int num=0; int n,m,S,T; int dis[MAXN]; int vis[MAXN]; int cur[MAXN]; void add_edge(int x,int y,int z) { edge[num].u=x; edge[num].v=y; edge[num].cap=z; edge[num].flow=0; edge[num].nxt=head[x]; head[x]=num++; } bool bfs(int bg,int ed) { memset(dis,-1,sizeof(dis)); queue<int>q; q.push(bg); dis[bg]=0; while(!q.empty()) { int p=q.front(); q.pop(); for(int i=head[p];i!=-1;i=edge[i].nxt) { if(dis[edge[i].v]==-1&&edge[i].cap>edge[i].flow) { vis[edge[i].v]=1; dis[edge[i].v]=dis[edge[i].u]+1; q.push(edge[i].v); } } } if(dis[ed]==-1) return 0; else return 1; } int dfs(int now,int a)// a:所有弧的最小残量 { if(now==T||a<=0) return a; int flow=0,f; for(int i=head[now];i!=-1;i=edge[i].nxt) { if(dis[now]+1==dis[edge[i].v]&&edge[i].cap-edge[i].flow>0) { f=dfs(edge[i].v,min(a,edge[i].cap-edge[i].flow)); edge[i].flow+=f; edge[i^1].flow-=f; flow+=f; a-=f; if(a<=0)break; } } return flow; } void Dinic(int S,int T) { int ansflow=0; for(int i=1;i<=n;i++) cur[i]=head[i]; while(bfs(S,T))// 求出层级 ansflow+=dfs(S,maxn); printf("%d",ansflow); } int main() { read(n);read(m); // swap(n,m); // S=1;T=m; read(S);read(T); for(int i=1;i<=n;i++) head[i]=-1; for(int i=1;i<=m;i++) { int x,y,z; read(x);read(y);read(z); add_edge(x,y,z); add_edge(y,x,0); } Dinic(S,T); return 0; }
update in 2017.7.29
补充一份加了当前弧优化&&把cap和flow两个变量合成一个的代码
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<algorithm> using namespace std; const int MAXN=10000001; const int MAXM=30000001; const int maxn=0x7fffff; inline void read(int &n) { char c='+';int x=0;bool flag=0; while(c<'0'||c>'9'){c=getchar();if(c=='-')flag=1;} while(c>='0'&&c<='9'){x=x*10+(c-48);c=getchar();} flag==1?n=-x:n=x; } struct node { int u,v,f,nxt; }edge[MAXM]; int head[MAXN]; int num=0; int n,m,s,t; inline void add_edge(int x,int y,int z) { edge[num].u=x; edge[num].v=y; edge[num].f=z; edge[num].nxt=head[x]; head[x]=num++; } int ans=0; int deep[MAXN]; int cur[MAXN]; inline bool bfs() { memset(deep,0,sizeof(deep)); deep[s]=1; queue<int>q; q.push(s); while(q.size()!=0) { int p=q.front(); q.pop(); for(int i=head[p];i!=-1;i=edge[i].nxt) if(!deep[edge[i].v]&&edge[i].f) { deep[edge[i].v]=deep[edge[i].u]+1; q.push(edge[i].v); } } return deep[t]; } int dfs(int now,int a) { if(now==t||a<=0) return a; int totflow=0,curflow; for(int &i=cur[now];i!=-1;i=edge[i].nxt) { if(edge[i].f&&deep[edge[i].v]==deep[edge[i].u]+1) { curflow=dfs(edge[i].v,min(a,edge[i].f)); edge[i].f-=curflow; edge[i^1].f+=curflow; totflow+=curflow; a-=curflow; if(a<=0) break; } } return totflow; } inline void Dinic() { while(bfs()) { for(int i=0;i<=n;i++) cur[i]=head[i]; ans+=dfs(s,maxn); } printf("%d",ans); } int main() { read(n);read(m);read(s);read(t); memset(head,-1,sizeof(head)); for(int i=1;i<=m;i++) { int x,y,z; read(x);read(y);read(z); add_edge(x,y,z); add_edge(y,x,0); } Dinic(); return 0; }
相关文章推荐
- P3376 【模板】网络最大流
- P3376 【模板】网络最大流
- P3376 【模板】网络最大流dinic算法
- P3376 【模板】网络最大流(70)
- Dinic算法 P3376 【模板】网络最大流
- P3376 【模板】网络最大流
- 洛谷 P3376【模板】网络最大流
- 洛谷 P3376 【模板】网络最大流
- 洛谷 P3376 【模板】网络最大流
- [模板练习]网络最大流
- 算法模板——sap网络最大流 3(递归+邻接表)
- 网络最大流(SAP)模板
- 最大网络流spa模板 优化的额
- 网络最大流(dinic)模板
- 网络最大流:模板(优化后)
- 算法模板——sap网络最大流 1(非递归+邻接矩阵)
- POJ 1459 Power Network(网络最大流,dinic算法模板题)
- 网络最大流-模板
- 洛谷P3376 【模板】网络最大流
- 【模板】网络最大流