poj1273 最大流

Ford-Fullkerson算法

 

#include  <iostream>
#include  <cstdio>
#include  <queue>
using namespace std;

int m,n,a,b,c,cost[201][201];
int Pre[201],Min[201],M=10000001;
bool visit[201];

int BFS()//寻找增广路 
{
    queue<int>  q;
    int temp;
    visit[1]=true;
    Pre[1]=0;
    Min[1]=M;
    q.push(1);
    while (!q.empty())
    {
        temp=q.front();
        q.pop();
        if (temp==n)  break;
        for (int i=1;i<=n;i++)
        {
            if (!visit[i]&&cost[temp][i])
            {
                Min[i]=(Min[temp]<cost[temp][i]) ? Min[temp] : cost[temp][i];
                Pre[i]=temp;
                visit[i]=true;
                q.push(i);
            }
        }
    }
    if (!visit[n]) return -1;
    else return   Min[n];   //一次遍历之后的流量增量
}

int Ford_Fulkerson()//求顶点1(源点)到顶点n(汇点)的最大流 
{
    int f,Max_Flow=0;
    while ((f=BFS())!=-1)//找不到增路径时退出
    {
        int temp=n;
        Max_Flow+=f;
        memset(visit,false,sizeof(visit));
        while (temp!=1)
        {
            int r=Pre[temp];
            cost[r][temp]-=f;  //更新正向边的实际容量
            cost[temp][r]+=f;  //添加反向边
            temp=r;
        }
    }
    return Max_Flow;
}

int main()
{
    while (scanf("%d%d",&m,&n)!=EOF)
    {
        memset(cost,0,sizeof(cost));
        for (int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            cost[a][b]+=c;
        }
        printf("%d\n",Ford_Fulkerson());
    }
    return 0;
}


 

Edmonds-Karp算法

 

#include<iostream>
#include<cstdio>
#include<queue> 
using namespace std; 

const int N = 210;
const int INF = 0x7FFFFFFF;
int n,m,map[N][N],path[N],flow[N],start,end;
queue<int> q;

int BFS()//寻找增广路 
{
    int i,t;
    while (!q.empty()) q.pop();
    memset(path,-1,sizeof(path));
    path[start]=0,flow[start]=INF;
    q.push(start);
    while (!q.empty())
    {
        t=q.front();
        q.pop();
        if (t==end) break;
        for (i=1;i<=n;i++)
        {
            if (i!=start && path[i]==-1 && map[t][i])
            {
                flow[i]=flow[t]<map[t][i]?flow[t]:map[t][i];
                q.push(i);
                path[i]=t;
            }
        }
    }
    if (path[end]==-1) return -1;
    return flow[n];                   //一次遍历之后的流量增量
}

int Edmonds_Karp()//求顶点1(源点)到顶点n(汇点)的最大流 
{
    int max_flow=0,step,now,pre;
    while ((step=BFS())!=-1) //找不到增路径时退出
    {
        max_flow+=step;
        now=end;
        while (now!=start)
        {
            pre=path[now];
            map[pre][now]-=step;      //更新正向边的实际容量
            map[now][pre]+=step;      //添加反向边
            now=pre;
        }
    }
    return max_flow;
}

int main()
{
    int i,u,v,w;
    while(scanf("%d%d",&m,&n)!=EOF)
    {
          memset(map,0,sizeof(map));
          for(i=0;i<m;i++)
          {
              scanf("%d%d%d",&u,&v,&w);
              map[u][v]+=w; //?? 两个点可能有多条路径,把权值相加           
          }     
          start=1;end=n;  
          printf("%d\n",Edmonds_Karp());        
    }
    //system("pause");
    return 0;

}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值