網絡流-dinic算法

//#include<bits/stdc++.h>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<queue>
#define LL long long
#define Max 100005
const LL mod=1e9+7;
const LL LL_MAX=9223372036854775807;
using namespace std;
struct node
{
    int v,next;
    LL w;
}edge[Max];
int dis[Max],head[Max],cur[Max];//dis代表深度,cur代表當前訪問到的節點,head鏈表
int index;
int st,en;
int n,m,u,v;
LL w;
queue<int>p;
void init(){
    index=0;
    memset(head,-1,sizeof(head));
}
void add(int u,int v,LL w){
    edge[index].v=v,edge[index].w=w;
    edge[index].next=head[u],head[u]=index++;

    edge[index].v=u,edge[index].w=0;
    edge[index].next=head[v],head[v]=index++;
}
bool bfs(){//構造出層次
    memset(dis,0,sizeof(dis));
    while(p.size())
        p.pop();
    dis[st]=1;
    p.push(st);
    while(p.size()){
        int top=p.front();
        p.pop();
        for(int t=head[top];t!=-1;t=edge[t].next)
            if(dis[edge[t].v]==0 && edge[t].w>0)
                dis[edge[t].v]=dis[top]+1,p.push(edge[t].v);
    }
    return dis[en]!=0;
}
LL dfs(int u,LL flow){//dfs擴展路徑
    if(u==en)
        return flow;
    for(int& t=cur[u];t!=-1;t=edge[t].next){
        if(dis[edge[t].v]==dis[u]+1 && edge[t].w>0){
            int mn=dfs(edge[t].v,min(flow,edge[t].w));
            if(mn>0){
                edge[t].w-=mn;
                edge[t^1].w+=mn;
                return mn;
            }
        }
    }
    return 0;
}
LL Dinic()
{
    LL ans=0;
    while(bfs()){
        for(int i=1;i<=n;i++)
            cur[i]=head[i];
        while(LL mn=dfs(1,LL_MAX)){
            ans+=mn;
        }

    }
    return ans;
}
int main()
{
    while(scanf("%d%d",&m,&n)==2){
        int u,v;
        LL w;
        init();
        for(int i=0;i<m;i++){
            scanf("%d%d%lld",&u,&v,&w);
            add(u,v,w);
        }
        st=1,en=n;
        printf("%lld\n",Dinic());
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章