模板:Edmonds_Karp 算法

題目見USACO草地排水一題

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<queue>
#include<vector>
#include<climits>
#include<string>
#include<cstdlib>
#include<set>
#include<stack>
#include<map>
#include<bitset>
#include<ctime>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
inline ll read()
{
    char k=0;char ls;ls=getchar();for(;ls<'0'||ls>'9';k=ls,ls=getchar());
    ll x=0;for(;ls>='0'&&ls<='9';ls=getchar())x=x*10+ls-'0';
    if(k=='-')x=0-x;return x;
}

ll n,m;
struct E
{
    ll edge;
    ll zhi;
    ll s;
}a[3000];
ll last[3000];
ll back;
ll ans;
ll pre[3000];//前驅邊在a數組中的位置 
ll prn[3000];//前驅節點 


inline void Edmonds_karp()
{
    while(1)//不停尋找 
    {
        queue<ll>p;//隊列用來廣度優先搜索 
        ll minflow=INT_MAX;
        p.push(1);
        memset(pre,0,sizeof(pre));
        memset(prn,0,sizeof(prn));
        while(!p.empty())//進行搜索 
        {
            int u=p.front();
            p.pop();
            if(u==n)break;//找到終點就跳出了(已經找到一條增廣路徑) 
            for(int j=last[u];j;j=a[j].zhi)
            {
                if(a[j].s>0&&prn[a[j].edge]==0)//可行弧且沒有訪問過 
                {
                    pre[a[j].edge]=j;
                    prn[a[j].edge]=u;
                    p.push(a[j].edge);
                }
            }
        }
        if(prn[n]==0)break;//到達不了終點就結束算法 
        for(int i=n;i!=1;i=prn[i])//找到邊最小流量 
        minflow=min(minflow,a[pre[i]].s);
        for(int i=n;i!=1;i=prn[i])//將流量修改在各邊 
        {
            ll q=pre[i];
            a[q].s-=minflow;
            a[q^1].s+=minflow;
        }
        ans+=minflow;//找到一條增廣路徑,增加流量 
    }
}



int main()
{
    //freopen("dt.in","r",stdin);
    //freopen("dt.out","w",stdout);
    m=read();n=read();
    for(int i=1;i<=m;++i)
    {
        ll a1=read(),b1=read(),c1=read(); 
        a[++back].edge=b1;//建立正向邊 
        a[back].zhi=last[a1];
        a[back].s=c1;
        last[a1]=back;

        a[++back].edge=a1;//建立逆向邊 
        a[back].zhi=last[b1];
        a[back].s=0;
        last[b1]=back;
    }
    Edmonds_karp();//算法 
    cout<<ans<<endl;
    //fclose(stdin);
    //fclose(stdout);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章