最大流 isap 模板

存一個最大流isap的模板
直接填入m,n,S,T 就可以跑了

#include<cstdio>
#include<cstring>
#include<climits>
#include<algorithm>
#include<queue>
using namespace std;
int n,m,flow;
#define MAXN 1100
#define MAXM 550000
bool vis[MAXN];
int g[MAXN][MAXN],d[MAXN];
bool r[MAXN][MAXN];
int cd[MAXN];
int S,T;
inline int min(int a,int b)
{return a<b?a:b;}
void init(){
    queue<int> que;
    que.push(T);
    vis[T]=true;
    while(!que.empty()){
        int u=que.front();
        que.pop();
        vis[u]=false;
        for(int i=1;i<=n;i++)//權值爲1 = =
            if(r[u][i]&&d[i]>d[u]+1/*+r[u][i]*/){
                d[i]=d[u]+1;
                //printf("d[%d]:%d\n",i,d[i]);
                if(!vis[i]){
                    vis[i]=true;
                    que.push(i);
                }
            }
    }
    for(int i=1;i<=n;i++)
        if(d[i]<=n)cd[d[i]]++;
}
int aug(int u,int f){
    if(u==T)return f;
    //printf("at:%d %d\n",u,f);
    int uf=f;
    for(int i=1;i<=n;i++)
        if(g[u][i]&&d[i]==d[u]-1){
            int k=aug(i,min(g[u][i],uf));
            g[u][i]-=k;
            g[i][u]+=k;
            uf-=k;
            if(!uf)break;
        }
    if(uf==f){
        cd[d[u]]--;
        if(!cd[d[u]]){d[S]=n+1;return 0;}//GAP
        d[u]=n+1;//不能用INT_MAX 溢出就好玩了
        for(int i=1;i<=n;i++)
            if(g[u][i])d[u]=min(d[u],d[i]+1);
        cd[d[u]]++;
    }
    return f-uf;
}
void sap(){
    for(int i=0;i<=n;i++)d[i]=0x3f3f3f3f;
    d[T]=0;
    init();
    while(d[S]<n)flow+=aug(S,INT_MAX);
}
inline void addedge(int a,int b,int c){
    g[a][b]+=c;
    r[b][a]=true;
}
int main(){
    scanf("%d%d",&m,&n);
    for(int i=1;i<=m;i++){
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        addedge(a,b,c);
    }
    S=1;
    T=n;
    sap();
    printf("%d\n",flow);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章