网络流之最大流(HDU 3549)EK算法与Dinic算法解决

欢迎阅读此篇博客(welcome)

给你一个N个顶点M条边的有向图,要你求1号点到N号点的最大流。最大流的EK模板。(此题不需要建立图的模型,比较基础,做一做有益身心健康)

那直接上EK模板的代码了:

#include<bits/stdc++.h>

using namespace std;

const int MAX_V = 10010;
const int INF = 0x3f3f3f3f;
struct Edge{
    int to,cap,rev;
};
//rev是一条逆边,就是有向边的反向,rev指向的是u的第几条边
vector<Edge> G[MAX_V];

void add(int u,int v,int cap){
    G[u].push_back((Edge){v,cap,(int)G[v].size()});
    G[v].push_back((Edge){u,0,(int)G[u].size()-1});
}
bool used[MAX_V];
int dfs(int s,int t,int f){
    if(s == t)  return f;
    used[s] = true;
    for(int i=0;i<G[s].size();i++){
        Edge &e = G[s][i];
        if(!used[e.to] && e.cap > 0){
            int d = dfs(e.to,t,min(f,e.cap));
            if(d > 0){
                e.cap -= d;
                G[e.to][e.rev].cap += d;
                return d;
            }
        }
    }
    return 0;
}

int solve(int s,int t){
    int res = 0;
    while(true){
        memset(used,false,sizeof(used));
        int f = dfs(s,t,INF);
        if(f == 0)   return res;
        res += f;
    }
}
int main(void){
    int t,V,E;
    int Case = 0;
    scanf("%d",&t);
    while(t--){
        scanf("%d %d",&V,&E);
        for(int i=1;i<=V;i++)
            G[i].clear();
        int x,y,z;
        for(int i=1;i<=E;i++){
            scanf("%d %d %d",&x,&y,&z);
            add(x,y,z);
        }
        printf("Case %d: ",++Case);
        printf("%d\n",solve(1,V));
    }
    return 0;
}

Dinic算法代码:

#include<bits/stdc++.h>

using namespace std;
const int MAX_V = 10010;
const int INF = 0x3f3f3f3f;
struct Edge{
    int to,cap,rev;
};
vector<Edge> G[MAX_V];
int level[MAX_V],iter[MAX_V];

void add(int u,int v,int cap){
    G[u].push_back((Edge){v,cap,(int)G[v].size()});
    G[v].push_back((Edge){u,0,(int)G[u].size()-1});
}

void bfs(int s){
    memset(level,-1,sizeof(level));
    queue<int> q;
    level[s] = 0;q.push(s);
    while(!q.empty()){
        int v = q.front();q.pop();
        for(int i=0;i<G[v].size();i++){
            Edge &e = G[v][i];
            if(e.cap > 0 && level[e.to] < 0){
                level[e.to] = level[v] + 1;
                q.push(e.to);
            }
        }
    }
}

int dfs(int s,int t,int f){
    if(s == t)  return f;
    for(int &i = iter[s];i < G[s].size();i++){
        Edge &e = G[s][i];
        if(e.cap > 0 && level[e.to] > level[s]){
            int d = dfs(e.to,t,min(f,e.cap));
            if(d > 0){
                e.cap -= d;
                G[e.to][e.rev].cap += d;
                return d;
            }
        }
    }
    return 0;
}

int solve(int s,int t){
    int res = 0;
    while(true){
        bfs(s);
        if(level[t] < 0)    return res;
        memset(iter,0,sizeof(iter));
        int f;
        while((f = dfs(s,t,INF)) > 0)
            res += f;
    }
}
int main(void){
    int t,V,E;
    int Case = 0;
    scanf("%d",&t);
    while(t--){
        scanf("%d %d",&V,&E);
        for(int i=0;i<=V;i++)
            G[i].clear();
        int x,y,z;
        for(int i=1;i<=E;i++){
            scanf("%d %d %d",&x,&y,&z);
            add(x,y,z);
        }
        printf("Case %d: ",++Case);
        printf("%d\n",solve(1,V));
    }


    return 0;
}

文章部分为转载,希望能帮助上你,一起进步吧~~~

猜你喜欢

转载自blog.csdn.net/qq_41995906/article/details/81266821