博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hdu 3549 Flow Problem Edmonds_Karp算法求解最大流
阅读量:5256 次
发布时间:2019-06-14

本文共 2421 字,大约阅读时间需要 8 分钟。

题意:N个顶点M条边,(2 <= N <= 15, 0 <= M <= 1000)问从1到N的最大流量为多少?

分析:直接使用Edmonds_Karp算法即可;下面是对增广路的一些理解和代码的解释;

残量:容量-流量;

增广:求出从源点到汇点的一条道路中所有残量的最小值d,把对应的所有边上的流量增加d,反向边(t->s)流量减少d(反向边的cap其实一直是0,只是flow为负了);

技巧:这次的ins的标号是从0开始的,即tot++,之前我都是++tot;这样head初始化就变为-1了,不能再是0;这样是为了每条边和其反向边的编号是存在XOR关系;即每次找到一条道路后从t找回到s(所以要在边中加入from)对每条边及其反向边的残量变化;

注意:同时增广路可达到所有边数的两倍;以及每次寻找路径的时候要把queue清空,否则MLE..

Edmond_Karp算法BFS查找每次需要O(m)总时间复杂度为O(n*m2),不够快所以跑了218ms

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;#define rep0(i,l,r) for(int i = (l);i < (r);i++)#define rep1(i,l,r) for(int i = (l);i <= (r);i++)#define rep_0(i,r,l) for(int i = (r);i > (l);i--)#define rep_1(i,r,l) for(int i = (r);i >= (l);i--)#define MS0(a) memset(a,0,sizeof(a))#define MS1(a) memset(a,-1,sizeof(a))#define inf 0x3f3f3f3f#define pb push_backtemplate
void read1(T &m){ T x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} m = x*f;}template
void read2(T &a,T &b){read1(a);read1(b);}template
void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);}template
void out(T a){ if(a>9) out(a/10); putchar(a%10+'0');}const int M = 1000;const int N = 20;int head[M<<1],tot;struct edge{ int from,to,cap,flow,Next;}e[M<<1];void ins(int u,int v,int cap,int flow){ e[tot].Next = head[u]; e[tot].from = u;//为了t->s时由v推到u; e[tot].to = v; e[tot].cap = cap; e[tot].flow = flow; head[u] = tot++;}queue
q;int p[N];//记录路径中边的标号int a[N];//起点到i的可改进量int Edmonds_Karp(int s,int t){ int flow = 0; for(;;){ MS0(a); while(!q.empty()) q.pop(); a[s] = inf; q.push(s); while(!q.empty()){ int u = q.front();q.pop(); for(int id = head[u];~id;id = e[id].Next){ int v = e[id].to,c = e[id].cap,f = e[id].flow; if(!a[v] && c > f){ p[v] = id; a[v] = min(a[u],c - f);// ** 递推到a[v] q.push(v); } } if(a[t]) break; } if(!a[t]) break; for(int u = t;u != s;u = e[p[u]].from){ e[p[u]].flow += a[t]; e[p[u]^1].flow -= a[t]; } flow += a[t]; } return flow;}int main(){ int n,T,kase = 1; read1(T); while(T--){ int V,E; read2(V,E); MS1(head);tot = 0; rep0(i,0,E){ int u,v,w; read3(u,v,w); ins(u,v,w,0);ins(v,u,0,0); } printf("Case %d: ",kase++); out(Edmonds_Karp(1,V)); puts(""); } return 0;}

 

转载于:https://www.cnblogs.com/hxer/p/5187231.html

你可能感兴趣的文章
第十二次作业
查看>>
喜欢的话
查看>>
[jQuery]在WCF 4中如何用JSONP轻松实现跨域Ajax请求
查看>>
JMS消息
查看>>
16位整数,32位整数,64位整数
查看>>
Jenkins+ProGet+Windows Batch搭建全自动的内部包(NuGet)打包和推送及管理平台
查看>>
Jenkins里邮件插件触发器配置和Send to Developers到底是什么意思(转)
查看>>
angular/cli安装
查看>>
GridView中某一列值的总和(web)
查看>>
简单的二分查找
查看>>
PHP输出缓存ob系列函数详解
查看>>
log4j 文档
查看>>
解析大型.NET ERP系统 设计通用Microsoft Excel导入功能
查看>>
Java_week2
查看>>
网页记账本开发三
查看>>
数据库的三层架构
查看>>
解析xml文件
查看>>
关于浏览器事件的思考
查看>>
jsp EL表达式 字符串的比较
查看>>
12.java.lang.NoSuchMethodException
查看>>