p1273最大流(模板)

来源:互联网 发布:sql delete select语句 编辑:程序博客网 时间:2024/06/05 05:04

先是自己写的,过不了,不知道有哪些特殊案例想不出来,当模板的记下咯

//

//  main.cpp

//  p1273

//

//  Created by Mr.Xue on 17/4/12.

//  Copyright © 2017 Mr.Xue. All rights reserved.

//


八月末更新:忘了最大流问题重新看了下模板,也找到了自己的代码的问题,就是初始化没做好,新的可以过 _ _ _

                          

                                               |

                   \/

  

#include <iostream>

#include <queue>

#include <math.h>

#define N  500

using namespacestd;

int tu[500][500],pre[500];

int cap[N][N],a[N],p[N];

int n,m,minx;

long longint sum=0;

int BFS(int sr,int ed)

{

    memset(a,0,sizeof(a));

    int index=0;

    for(int i=1;i<=n;i++)

        pre[i]=-1;

    queue<int>q;

    while(!q.empty())

        q.pop();

    q.push(1);

    a[sr]=10000000;

    //flag[sr]=1;

    while(!q.empty())

    {

        index=q.front();

        q.pop();

        //flag[index]=0;

        for(int i=1;i<=n;i++)

        {

            if(!a[i]&&tu[index][i]>cap[index][i])

            {

                a[i]=min(tu[index][i]-cap[index][i],a[index]);

                pre[i]=index;

                q.push(i);

            }

        }

    }

    if(a[ed]==0)

        return -1;

    else

        return1;

}

void addFlow()

{

    sum=0;

    while(BFS(1,n)!=-1)

    {

        int index,i=n;

        sum=sum+a[n];

        //printf("\n************%d\n",minx);

        while(1)

        {

            index=pre[i];

            cap[index][i]+=a[n];

            cap[i][index]-=a[n];

            if(index==1)

                break;

            i=index;

        }

        //printf("\n");

    }

}

int main()

{

    int a,b,c;

    while(scanf("%d %d",&m,&n)!=EOF)

    {

        memset(tu,0,sizeof(tu));

        memset(cap,0,sizeof(cap));

        for(int i=0;i<m;i++)

        {

            scanf("%d %d %d",&a,&b,&c);

            tu[a][b]+=c;

        }

        addFlow();

        printf("%lld\n",sum);

    }

    return0;

}



网上的

#include<iostream>

#include<queue>

using namespace std;

const int N=201;

const int INF=99999999;

int n,m,sum,s,t;//s,t为始点和终点

int flow[N][N],cap[N][N],a[N],p[N];

//分别为:flow[u][v]<u,v>流量、cap[u][v]<u,v>容量、a[i]表示源点s到节点i的路径上的最小残留量、p[i]记录i的前驱

int min(int a,int b)

{

    return a<=b?a:b;

}

void Edmonds_Karp()

{

    int i,u,v;

    queue<int>q;//队列,用bfs找增广路

    while(1)

    {

        memset(a,0,sizeof(a));//每找一次,初始化一次

        a[s]=INF;

        q.push(s);//源点入队

        while(!q.empty())

        {

            u=q.front();

            q.pop();

            for(v=1;v<=m;v++)

            {

                if(!a[v]&&flow[u][v]<cap[u][v])

                {

                    p[v]=u;

                    q.push(v);

                    a[v]=min(a[u],cap[u][v]-flow[u][v]);//s-v路径上的最小残量

                }

            }

        }

        if(a[m]==0)//找不到增广路,则当前流已经是最大流

            break;

        sum+=a[m];//流加上

        for(i=m;i!=s;i=p[i])// //从汇点顺着这条增广路往回走

        {

            flow[p[i]][i]+=a[m];//更新正向流量

            flow[i][p[i]]-=a[m];//更新反向流量

        }

    }

    printf("%d\n",sum);

}

int main()

{

    //freopen("in.txt","r",stdin);

    int v,u,w;

    while(scanf("%d%d",&n,&m)!=EOF)

    {

        s=1;//1开始

        t=m;//m为汇点

        sum=0;//记录最大流量  

        memset(flow,0,sizeof(flow));//初始化  

        memset(cap,0,sizeof(cap));  

        while(n--)  

        {  

            scanf("%d%d%d",&u,&v,&w);  

            cap[u][v]+=w;//注意图中可能出现相同的边  

        }  

        Edmonds_Karp();  

    }  

    return0;  

}




0 0
原创粉丝点击