最大流 EdmondsKarp演算法
Edmonds_Karp演算法模板
鄰接矩陣形式
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
const int N=205;
const int INF=0x3f3f3f3f;
int g[N][N];
int pre[N];//路徑上每個結點的前驅結點
bool vis[N];
int n,m;//m是頂點數目,頂點編號從1開始 1是源,m是匯,n是邊數
int EdmondsKarp()
{
int i,v;
queue<int>q;
memset(pre,-1,sizeof(-1));
memset(vis,0,sizeof(vis));
pre[1]=0;
vis[1]=1;
q.push(1);
bool flag=false;//標記bfs是否尋找到一條源到匯的可行路徑
while(!q.empty()){
v=q.front();
q.pop();
for(int i=1;i<=m;i++)
if(g[v][i]>0&&vis[i]==0){//必須是依然有容量的邊,才可以走
pre[i]=v;
vis[i]=1;
if(i==m){
flag=true;
break;
}
else
q.push(i);
}
}
if(!flag)//找不到就退出
return 0;
int ans=INF;
v=m;
//尋找源到匯路徑上容量最小的邊,其容量就是此次增加的總流量
while(pre[v]){
ans=min(ans,g[pre[v]][v]);
v=pre[v];
}
//沿此路徑新增反向邊,同時修改路徑上每條邊的容量
v=m;
while(pre[v]){
g[pre[v]][v]-=ans;
g[v][pre[v]]+=ans;
v=pre[v];
}
return ans;
}
int main()
{
while(cin>>n>>m){//m是頂點數目,頂點編號從1開始
int s,e,c;
memset(g,0,sizeof(g));
for(int i=1;i<=n;i++){
cin>>s>>e>>c;
g[s][e]+=c;//兩點之間可能有多條邊
}
int ans=0,tmp;
while(tmp=EdmondsKarp())
ans+=tmp;
cout<<ans<<endl;
}
return 0;
}
鄰接表形式(前向星實現)
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int N=4005;
const int INF=0x3f3f3f3f;
//前向星實現圖的鄰接表
int M,head[N];
struct Edge{
int next,to,w;
}edge[N];
void add(int from,int to,int w)
{
edge[M].next=head[from];
edge[M].to=to;
edge[M].w=w;
head[from]=M++;
}
struct Pre{
int u,id;
}pre[N];
bool vis[N];
int n,m;
int EdmondsKarp()
{
queue<int>q;
memset(vis,false,sizeof(vis));
vis[1]=true;
q.push(1);
bool flag=false;
int u,v,w;
//尋找從源到匯的一條增廣路徑
while(!q.empty())
{
u=q.front();
q.pop();
for(int k=head[u];k!=-1;k=edge[k].next)
{
v=edge[k].to;
w=edge[k].w;
if(w>0&&!vis[v])//必須是依然有容量的邊,才可以走
{
pre[v].u=u;//記錄v的前驅結點
pre[v].id=k;//記錄 u->v的邊號
vis[v]=true;
if(v==n)
{
flag=true;//找到一條增廣路徑
break;
}
else
q.push(v);
}
}
}
if(!flag)//找不到就退出
return 0;
int ans=INF;
//尋找源到匯路徑上容量最小的邊,其容量就是此次增加的總流量
for(v=n;v!=1;v=pre[v].u)
ans=min(ans,edge[pre[v].id].w);
//沿此路徑新增反向邊,同時修改路徑上每條邊的容量
for(v=n;v!=1;v=pre[v].u)
{
edge[pre[v].id].w-=ans;
edge[(pre[v].id)^1].w+=ans;// (pre[v].id)^1是編號為 pre[v].id的反向邊編號
}
return ans;
}
int main()
{
while(~scanf("%d%d",&m,&n))
{
int from,to,w;
M=0;
memset(head,-1,sizeof(head));
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&from,&to,&w);
add(from,to,w);
add(to,from,0);//新增反向邊
}
int ans=0,temp;
while(temp=EdmondsKarp())
ans+=temp;
printf("%d\n",ans);
}
return 0;
}
相關文章
- 最大流 dinic演算法演算法
- 網路最大流演算法演算法
- 網路最大流 Dinic演算法演算法
- 經典演算法-最大流問題演算法
- poj 3436 最大流的增廣路演算法演算法
- POJ 3469-Dual Core CPU(Dinic 最大流/最小割演算法)演算法
- POJ 2195-Going Home(KM演算法/最小費用最大流演算法)Go演算法
- (通俗易懂小白入門)網路流最大流——EK演算法演算法
- 【機器學習】深度解析機器學習五大流派中主演算法精髓機器學習演算法
- 最大流題目
- EK求最大流
- 最大流學習筆記(5)-前置重貼標籤演算法一筆記演算法
- POJ 1459-Power Network(最大流-Edmond-Karp演算法)演算法
- 最優排序演算法排序演算法
- 網路流最大流
- Dinic/ISAP求最大流
- 演算法:最長公共字首演算法
- POJ 1273-Drainage Ditches(最大流-Edmond-Karp演算法/模板)AI演算法
- 淺談網路最大流
- hdu 4292 網路最大流
- 有源匯上下界最大流
- 【模板】網路流最大流
- POJ 3436-ACM Computer Factory(最大流輸出路徑-Edmond-Karp演算法)ACM演算法
- 演算法金 | 突破最強演算法模型,決策樹演算法!!演算法模型
- [譯] Swift 演算法學院 - 最長公共子序列演算法Swift演算法
- 網路流(最大流,最小割)
- 一維下的最優演算法演算法
- 演算法之字串——最長公共字首演算法字串
- 演算法題:最長公共子序列演算法
- 最優化演算法【牛頓法、擬牛頓法、BFGS演算法】優化演算法
- 演算法 - 最好、最壞、平均複雜度演算法複雜度
- 最核心的特徵工程方法-分箱演算法特徵工程演算法
- 最基礎的分類演算法(KNN)演算法KNN
- 世界上最漂亮的排序演算法!排序演算法
- 演算法學習之路|最簡分數演算法
- LCS 演算法:Javascript 最長公共子序列演算法JavaScript
- 演算法-兩最長迴文子串演算法
- 網路中最小費用最大流