最大流(三)—— Dinic算法

因为没打优化,比打了优化的SAP算法慢了很多,超时了。

#include<vector>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<queue>
#define numm ch-48
#define pd putchar(' ')
#define pn putchar('\n')
#define pb push_back
#define fi first
#define se second
#define fre1 freopen("1.txt","r",stdin)
#define fre2 freopen("2.txt","w",stdout)
using namespace std;
template <typename T>
void read(T &res) {
    bool flag=false;char ch;
    while(!isdigit(ch=getchar())) (ch=='-')&&(flag=true);
    for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm);
    flag&&(res=-res);
}
template <typename T>
void write(T x) {
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
}
const int maxm=8000010;     ///有反向边,边数要开两倍
const int maxn=1000010;
const int inf=0x3f3f3f3f;
const int INF=0x7fffffff;
typedef long long ll;
struct node {   ///链式前向星
    ll c;
    int to,net;
}e[maxm];
int head[maxn],level[maxn],que[maxn];
int n,cnt=0;
void init() {
//    cnt=0;
//    for(int i=1;i<=n;i++)   ///单测试用例可不用
//        level[i]=0;
    for(int i=1;i<=n;i++)
        head[i]=-1;
}
void add(int u,int v,ll c) {
    e[cnt].to=v;
    e[cnt].c=c;
    e[cnt].net=head[u];
    head[u]=cnt++;
}
bool bfs(int st,int ed) {
    int iq=0;
    for(int i=1;i<=n;i++)
        level[i]=0;
    level[st]=1;
    que[iq++]=st;
    for(int i=0;i<iq;i++) {
        int top=que[i];
        if(top == ed) return true;
        for(int k=head[top];k!=-1;k=e[k].net)
            if(!level[e[k].to]&&e[k].c) {
                que[iq++]=e[k].to;
                level[e[k].to]=level[top]+1;
            }
    }
    return false;
}
ll dfs(int now,ll max_flows,int ed) {
    if(now==ed) return max_flows;
    ll res=0;
    for(int k=head[now];k!=-1;k=e[k].net)
        if(e[k].c&&level[e[k].to]==level[now]+1) {
            ll f=dfs(e[k].to,min(max_flows-res,e[k].c),ed);
            res+=f;
            e[k].c-=f;
            e[k^1].c+=f;
            if(res == max_flows) return res;
        }
    return res;
}
ll Dinic(int st,int ed) {
    ll max_flows=0;
    while(bfs(st,ed)) max_flows+=dfs(st,INF,ed);
    return max_flows;
}
int main()
{
    int st,m,ed;
    read(n),read(m),read(st),read(ed);
    init();
    for(int i=1;i<=m;i++) {
        int u,v;
        ll c;
        read(u),read(v),read(c);
        add(u,v,c);
        add(v,u,0);     ///建立反向边
    }
    write(Dinic(st,ed));pn;
    return 0;
}
///Dinic算法

  

posted @ 2019-07-17 15:21  wuliking  阅读(205)  评论(0编辑  收藏  举报