网络流--队列

    //Edmonds_Karp  
    #include  
    #include  
    #include 
    #include
    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]为流量、cap[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]//s-v路径上的最小残量  
                    }  
                }  
                if(u==m)break;
            }  
            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(){  
        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();  
        }  
        return 0;  
    }  

你可能感兴趣的:(网络流)