程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> POJ 1273 Drainage Ditches 最大流-EdmondsKarp(EK)

POJ 1273 Drainage Ditches 最大流-EdmondsKarp(EK)

編輯:C++入門知識

[cpp] 
#include <set> 
#include <map> 
#include <list> 
#include <cmath> 
#include <ctime> 
#include <deque> 
#include <queue> 
#include <stack> 
#include <cctype> 
#include <cstdio> 
#include <string> 
#include <vector> 
#include <cassert> 
#include <cstdlib> 
#include <cstring> 
#include <sstream> 
#include <iostream> 
#include <algorithm> 
using namespace std; 
int max(int a,int b){return a<b?b:a;} 
int min(int a,int b){return a>b?b:a;} 
#define V 205 
#define INF 0x3f3f3f3f 
int cap[V][V],flow[V][V];// cap是每條邊的容量,flow是每條邊的流量 
int res[V],father[V];//res[]是每個點的剩余流量,father[]是每個點的父親 
int s,t,u,v,f=0; //f是最大流 
int m,n,a,b,c; 
int EK(int s,int t)  //白書EK模板,加點注釋大家比較容易理解 

    f=0; 
    queue<int> q; 
    memset(flow ,0,sizeof(flow)); //最開始每條邊的流量都是0 
    while(1) 
    { 
        memset(res,0,sizeof(res)); //殘余流量得變0,一開始所有點都沒流入對吧 
        res[s]=INF; //源點嘛,剩余流量無限是必須的... 
        q.push(s); //從源點開始進行BFS找增廣路 
        while(!q.empty()) 
        { 
            u = q.front(); //取隊頭 
            q.pop(); 
            for(v=1;v<=n;v++) //遍歷所有點,找可行邊 
            { 
                if(!res[v] && cap[u][v]>flow[u][v])  //該點剩余流量為0 且 容量大於流量,也就是找到了新的結點 
                { 
                    father[v]=u;//找到新結點,父節點得記錄一下吧 
                    q.push(v); //明顯新結點要入隊列 
                    res[v]=min(res[u],cap[u][v]-flow[u][v]);//如果u的剩余流量能填滿uv就填滿,不能的話就把u這點的流量全部流向uv 
                } 
            } 
        } 
        if(res[t]==0) //如果當前已經是最大流,匯點沒有殘余流量 
            return f; 
        for(u=t;u!=s;u=father[u]) //如果還能增廣,那麼回溯,從匯點往回更新每條走過的邊的流量 
        { 
            flow[father[u]][u]+=res[t];  //更新正向流量 
            flow[u][father[u]]-=res[t];  //更新反向流量 
        }  www.2cto.com
        f+=res[t];  //找到可增廣的流量真開心 
    } 

int main() 

    while(cin>>m>>n)//萬惡多組,貢獻一次WA 
    { 
        memset(cap,0,sizeof(cap)); 
        memset(flow,0,sizeof(flow)); 
        memset(father,0,sizeof(father)); 
        memset(res,0,sizeof(res)); 
        while(m--) 
        { 
            cin>>a>>b>>c; 
            cap[a][b]+=c; //萬惡重邊,再貢獻一次WA 
        } 
        cout<<EK(1,n)<<endl; 
    } 
    return 0; 

有史以來注釋最多的EK了...

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved