网络流之最大流算法模板EK
来源:互联网 发布:网络板块股票有哪些 编辑:程序博客网 时间:2024/05/10 10:06
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
int maxdata=0x7fffffff;
int capacity[200][200],c[1000][1000];//c[i][j]保存初值,因为每次计算都会改变capacity[i][j]的值,capacity[i][j]表示残留网络的容量
int flow[200];//标记从源点到当前点实际还有多少容量可用
int pre[200];//标记在这条路径上当前节点的前驱,同时标记该节点是否在队列中
int x[1000],y[10000],len[10000];//x,y,len存储每条边的信息
int n,m,p; //n 表示边数,m表示节点数,p表示操作数
queue<int> myqueue;
int bfs(int src,int des)
{
int i,j;
while(!myqueue.empty())//队列清空
myqueue.pop();
for (i=1;i<m+1;i++)
pre[i]=-1;//pre[i]=-1表示该点没有入队
pre[src]=0;
flow[src]=maxdata;
myqueue.push(src);
while (!myqueue.empty())
{
int index=myqueue.front();
myqueue.pop();
if (index==des)//index==des说明所有到终点的路已经都搜索完了
break;
for (i=1;i<m+1;i++)
{
if (i!=src&&capacity[index][i]>0&&pre[i]==-1)//i不是源点,且从当前点可以到达i点,i点不在队列中,则i点入队
{
pre[i]=index;//该路径上i的前驱点为index
flow[i]=min(capacity[index][i],flow[index]);//要通过必须满足流量小于等于所有边的最小值
myqueue.push(i);
}
}
}
if (pre[des]==-1)
return -1;
else
return flow[des];
}
int maxflow(int src,int des)//src表示源点,des表示汇点
{
int increasement=0;
int sumflow=0;
while((increasement=bfs(src,des))!=-1)//有可以流到汇点的路径
{
int k=des;
while (k!=src)
{
int last=pre[k];
capacity[last][k]-=increasement;//用路径上每一条边的容量减去该路径的流量
capacity[k][last]+=increasement;//给程序反悔和改正的机会
k=last;
}
sumflow+=increasement;
}
return sumflow;
}
int main()
{
freopen("b.in","r",stdin);
freopen("b.out","w",stdout);
int i,j,l;
int start,end,ci;
cin>>m>>n;
memset(capacity,0,sizeof(capacity));
memset(flow,0,sizeof(flow));
for (i=1;i<=n;i++)
{
cin>>start>>end>>ci;
x[i]=start; y[i]=end; len[i]=ci;
if (start==end)
continue;
c[start][end]=capacity[start][end]+=ci;
c[end][start]=capacity[end][start]+=ci;
}
scanf("%d",&p);
for (l=1;l<=p;l++)
{
int x1,y1,z1;
for (i=1;i<=m;i++)
for (j=1;j<=m;j++)
capacity[i][j]=c[i][j];
scanf("%d%d%d",&x1,&y1,&z1);
if (x1==0)
printf("%d\n",maxflow(y1,z1));
if (x1==1)//改变编号Y1的边的容量,
{
c[x[y1]][y[y1]]=capacity[x[y1]][y[y1]]=z1;
c[y[y1]][x[y1]]=capacity[y[y1]][x[y1]]=z1;
}
}
}//如果把网络流的图看作一系列的管道,那么求最大流就相当于从源点处注水,求最多最终有多少水可以流到汇点
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
int maxdata=0x7fffffff;
int capacity[200][200],c[1000][1000];//c[i][j]保存初值,因为每次计算都会改变capacity[i][j]的值,capacity[i][j]表示残留网络的容量
int flow[200];//标记从源点到当前点实际还有多少容量可用
int pre[200];//标记在这条路径上当前节点的前驱,同时标记该节点是否在队列中
int x[1000],y[10000],len[10000];//x,y,len存储每条边的信息
int n,m,p; //n 表示边数,m表示节点数,p表示操作数
queue<int> myqueue;
int bfs(int src,int des)
{
int i,j;
while(!myqueue.empty())//队列清空
myqueue.pop();
for (i=1;i<m+1;i++)
pre[i]=-1;//pre[i]=-1表示该点没有入队
pre[src]=0;
flow[src]=maxdata;
myqueue.push(src);
while (!myqueue.empty())
{
int index=myqueue.front();
myqueue.pop();
if (index==des)//index==des说明所有到终点的路已经都搜索完了
break;
for (i=1;i<m+1;i++)
{
if (i!=src&&capacity[index][i]>0&&pre[i]==-1)//i不是源点,且从当前点可以到达i点,i点不在队列中,则i点入队
{
pre[i]=index;//该路径上i的前驱点为index
flow[i]=min(capacity[index][i],flow[index]);//要通过必须满足流量小于等于所有边的最小值
myqueue.push(i);
}
}
}
if (pre[des]==-1)
return -1;
else
return flow[des];
}
int maxflow(int src,int des)//src表示源点,des表示汇点
{
int increasement=0;
int sumflow=0;
while((increasement=bfs(src,des))!=-1)//有可以流到汇点的路径
{
int k=des;
while (k!=src)
{
int last=pre[k];
capacity[last][k]-=increasement;//用路径上每一条边的容量减去该路径的流量
capacity[k][last]+=increasement;//给程序反悔和改正的机会
k=last;
}
sumflow+=increasement;
}
return sumflow;
}
int main()
{
freopen("b.in","r",stdin);
freopen("b.out","w",stdout);
int i,j,l;
int start,end,ci;
cin>>m>>n;
memset(capacity,0,sizeof(capacity));
memset(flow,0,sizeof(flow));
for (i=1;i<=n;i++)
{
cin>>start>>end>>ci;
x[i]=start; y[i]=end; len[i]=ci;
if (start==end)
continue;
c[start][end]=capacity[start][end]+=ci;
c[end][start]=capacity[end][start]+=ci;
}
scanf("%d",&p);
for (l=1;l<=p;l++)
{
int x1,y1,z1;
for (i=1;i<=m;i++)
for (j=1;j<=m;j++)
capacity[i][j]=c[i][j];
scanf("%d%d%d",&x1,&y1,&z1);
if (x1==0)
printf("%d\n",maxflow(y1,z1));
if (x1==1)//改变编号Y1的边的容量,
{
c[x[y1]][y[y1]]=capacity[x[y1]][y[y1]]=z1;
c[y[y1]][x[y1]]=capacity[y[y1]][x[y1]]=z1;
}
}
}//如果把网络流的图看作一系列的管道,那么求最大流就相当于从源点处注水,求最多最终有多少水可以流到汇点
0 0
- 网络流之最大流算法模板EK
- 最大流EK算法模板
- 最大流EK算法模板
- 最大网络流 EK 算法
- 网络最大流 EK算法
- 网络最大流算法之 Ford_Fulkerson方法,EK算法 c++模板
- 网络最大流算法之Ford_Fullkerson方法,EK算法c++模板
- 【网络流之最大流】HDU3549Flow Problem【EK模板】
- 最大流之EK算法
- 最大流之EK算法模板(小白皮)
- HDU_1532 && HDU_3549(最大流EK算法模板)
- 最大流问题(EK算法模板)
- HDU1532(最大流EK算法模板题)
- 最大流DFS(EK)算法模板
- HDOJ1532 最大流 BFS + EK 算法 模板
- 网络流之EK 算法
- EK算法(网络流,最大流)
- 网络流--求最大流:EK算法
- 阅读源码策略之我见
- [BZOJ2442]修剪草坪
- Sicily 1790. Single Round Match
- 结合win32和MFC
- iOS framework 制作教程
- 网络流之最大流算法模板EK
- 分享一些第三方组件和开源的库
- 给shell脚本中加上执行日志
- Linux下openoffice+swftools安装教程
- 事件处理和消息响应
- Java抽象类用法示例详解
- button按钮不可点击
- bomb 多对多关系 查询问题:1)查询用户A所订阅的所有频道 2)查询订阅了频道B的所有用户
- JDBC类的封装 + 数据库连接池