网络流dinic模版

#include<cstdio>
#include<cstring>
#include<queue>
#define maxn 5005
using namespace std;
int n,m,ans;
int be[maxn],ne[maxn],to[maxn],e=0,w[maxn];//链表
int d[maxn];//记录搜索深度
int read(){
    int c=getchar(),fg=1,sum=0;
    while(c>'9'||c<'0'){
        if(c=='-')
            fg=-1;//如果是负数
        c=getchar();
    }
    while(c<='9'&&c>='0'){
        sum=sum*10+c-'0';
        c=getchar();
    }
    return fg*sum;
}
void add(int x,int y,int z){
    to[e]=y;//边e要到达的节点
    ne[e]=be[x];
    be[x]=e;
    w[e]+=z;//边e的最大流量
    e++;
}
int bfs(){
    memset(d,-1,sizeof(d));
    queue<int> q;
    q.push(n),d[n] = 0;
    while(!q.empty()){//队列非空
        int u=q.front();//取队头
        q.pop();//弹出队头
        for(int i=be[u];i!=-1;i=ne[i]){
            int v=to[i];
            if(w[i^1]&&d[v]==-1){
                d[v]=d[u]+1;
                q.push(v);
            }
        }
    }
    return d[1]!=-1;//可以连通
}
int dfs(int x,int flow){
    if(x==n)//已经搜到汇点
        return flow;
    int k;//增加的可以通过的流量
    for(int i=be[x];i!=-1;i=ne[i]){
        int v=to[i];
        if(w[i]&&d[v]==d[x]-1){//保证不出环
            k=dfs(v,min(flow,w[i]));//min保证可行性
            if(k>0){
                w[i]-=k;
                w[i^1]+=k;//^可以直接取到相反的边
                return k;
            }
        }
    }
    return 0;
}
int main(){
    scanf("%d%d",&m,&n);
    memset(be,-1,sizeof(be));
    for(int i=1;i<=m;i++){
        int x,y,z;
        x=read(),y=read(),z=read();
        to[e]=y;//边e要到达的节点
        ne[e]=be[x];
        be[x]=e;
        w[e]+=z;//边e的最大流量
        e++;
        to[e]=x;//边e要到达的节点
        ne[e]=be[y];
        be[y]=e;
        e++;
    }
    int k;
    while(bfs()){
        k=dfs(1,1e7);
        ans+=k;
    }
    printf("%d",ans);
    return 0;
}

 

posted @ 2018-01-19 10:45  AL76  阅读(126)  评论(0编辑  收藏  举报