网络最大流模板(标号法)
来源:互联网 发布:java 支付订单号生成 编辑:程序博客网 时间:2024/05/22 03:20
测试数据
6 10
0 1 8 2
0 2 4 3
1 3 2 2
1 4 2 2
2 1 4 2
2 3 1 1
2 4 4 0
3 4 6 0
3 5 9 3
4 5 7 2
0->1:4
0->2:4
1->3:2
1->4:2
2->1:0
2->3:1
2->4:3
3->4:0
3->5:3
4->5:5
max_flow=8
代码
#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>using namespace std;//标号法求矩阵网络最大流const int maxn=100;//顶点数量const int INF=0x3f3f3f3f;struct node{ int c;//容量 int f;//流量} map[maxn][maxn];int flag[maxn];//未访问标记为-1,已访问未检查邻接顶点标记为0,已访问已检查邻接顶点标记为1int prev[maxn];//i号顶点从prev[i]号顶点来int alpha[maxn];//当star指向i,alpha[i]=min(alpha[star],map[star][i].c-map[star][i].f)//当i指向star,alpha[i]=min(alpha[star],map[i][star].f);int queue[maxn];//模拟队列int N;//顶点int M;//弧数int q_star,q_end;//队列头尾指针void ford(){ while(1)//标号法可以在有限次标号调整后使求得最大流 { for(int i=0; i<N; i++) //初始化三个辅助数组 { flag[i]=-1; prev[i]=-1; alpha[i]=-1; } flag[0]=0;//源点标记为已访问未检查的点 prev[0]=0;//源点的上一个点还是源点 alpha[0]=INF;//源点可以无限流出 q_star=q_end=0; queue[q_end++]=0;//源点入队 while(q_star<q_end&&flag[N-1]==-1)//队列内有元素或者还没标记到汇点时进入循环接着标记 { int star=queue[q_star++];//去除队列元素 for(int i=0; i<N; i++) //检查star的邻接顶点,由于是有向图,所以需要检查正向邻接和反向邻接 { if(flag[i]==-1)//只检查尚未访问过的点,因为已访问未检查的点都在队列中 { //检查正向邻接,存在此弧且流量未满 if(map[star][i].c<INF&&map[star][i].f<map[star][i].c) { flag[i]=0;//标记为已访问未检查 prev[i]=star;//记录增广路径 alpha[i]=min(alpha[star],map[star][i].c-map[star][i].f);//可调整量 queue[q_end++]=i;//顶点i入队 } //检查反向邻接,存在弧且有流量 if(map[i][star].c<INF&&map[i][star].f>0) { flag[i]=0;//标记为已访问未检查 prev[i]=-star;//加个负号表示反向邻接 alpha[i]=min(alpha[star],map[i][star].f);//可调整量 queue[q_end++]=i;//入队 } } } flag[star]=1;//标记为已访问已检查 } if(flag[N-1]==-1||alpha[N-1]==0)//如果找不到去汇点的增广路径或者可调整量为0 break;//结束标号法 //下面这一步可能有问题 int alpha_num=alpha[N-1];//可调整量 int k1=N-1; int k2=abs(prev[k1]); while(1) { if(map[k2][k1].f<INF) map[k2][k1].f+=alpha_num; else map[k1][k2].f-=alpha_num; if(k2==0)//当调整到源点时跳出循环 break; k1=k2; k2=abs(prev[k2]);//不要忘了取绝对值 } } //下面输出各弧边最大流并累加 int max_flow=0;//累加各弧最大流 for(int i=0; i<N; i++) { for(int j=0; j<N; j++) { if(i==0&&map[i][j].f<INF) max_flow+=map[i][j].f; if(map[i][j].f<INF) printf("%d->%d:%d\n",i,j,map[i][j].f); } } printf("max_flow=%d\n",max_flow);}int main(){ scanf("%d%d",&N,&M); for(int i=0; i<N; i++) for(int j=0; j<N; j++) map[i][j].c=map[j][i].f=INF;//网络流都是有向图 int u,v,c,f; for(int i=0; i<M; i++) { scanf("%d%d%d%d",&u,&v,&c,&f); map[u][v].c=c; map[u][v].f=f; } ford(); return 0;}
0 0
- 网络最大流模板(标号法)
- POJ-1273-Drainage Ditches(网络最大流 标号法)
- Ford-Fulkerson 标号法求网络最大流
- 网络最大流中一般增广路算法(标号法)
- POJ 1149-PIGS(Ford-Fulkerson 标号法求网络最大流)
- 网络流之标号法
- POJ-1149-PIGS(最大流 标号法)
- 最大流的Ford-Fulkerson 标号法
- 最大网络流 模板
- 【模板】网络最大流
- 网络流(最大流+模板)
- 网络最大流(dinic)【模板】
- 网络最大流(SAP)【模板】
- 网络最大流(SAP)模板
- 网络最大流(dinic)模板
- 【模板】网络最大流 (Dinic)
- 网络最大流:模板(优化后)
- 【模板】ISAP网络最大流 (模板题:洛谷P3376)
- 安卓机视频进度条隐藏的研究
- 遍历Map的四种方式
- linux之C编程学习——进程,进程,进程!
- Symfony系列-路由
- Kubernetes初探
- 网络最大流模板(标号法)
- iOS横竖屏切换
- 初学python--报错: SyntaxError: Non-ASCII character '\xe5' in file
- Eclipse报错:java.lang.ClassNotFoundException: ContextLoaderListener
- Linux第六周学习总结——进程额管理和进程的创建
- Win32应用程序创建控制台
- HDU1698 线段树+区间更新+懒惰标记-Just a Hook
- Objective-C中的@property和@synthesize用法及参数(readwrite/readonly)(assign/retain/copy)(atomicity/nonatomic)
- safari浏览器下解决Date日期的NAN问题