• 图论:网络流最大流EK算法


    点击查看折叠代码块
    /*
    时间复杂度:
    O(N*M*M)
    */
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int inf=0x3f3f3f3f;
    const int maxn=210;
    const int maxm=5e3+10;
    int n,m,s,t;
    ll maxflow = 0,dis[maxn];
    
    struct edge{
        int v,next;
        ll c;
    }e[maxm<<2];
    int head[maxn],cnt=0;
    int pre[maxn];//pre存上一个点
    bool vis[maxn];
    int flag[maxn][maxn];
    
    void add(int u,int v,ll c){
        e[cnt].v=v;
        e[cnt].c=c;
        e[cnt].next=head[u];
        head[u]=cnt++;
    }
    
    bool bfs(int s,int t){
        for (int i=1;i<=n;i++) vis[i]=0;
        dis[s]=inf;
        vis[s]=1;
        queue<int> q;
        q.push(s);
        while(!q.empty()){
            int u=q.front();
            q.pop();
            for (int i=head[u];~i;i=e[i].next){
                int v=e[i].v;
                ll c=e[i].c;
                // cout<<"c = "<<c<<endl;
                if(c>0 && !vis[v]){
                    dis[v]=min(dis[u],c);
                    // cout<<"disv = "<<dis[v]<<endl;
                    pre[v] = i;
                    q.push(v);
                    vis[v]=1;
                    if(v==t) return 1;//找到了一条增广路
                }
            }
        }
        return 0;
    }
    
    void update(int s,int t){
        int x=t;
        while(x!=s){
            int v=pre[x];
            e[v].c-=dis[t];
            e[v^1].c+=dis[t];
            x=e[v^1].v;
        }
        maxflow+=dis[t];
    }
    
    void EK(){
        while(bfs(s,t)){
            update(s,t);
        }
    }
    
    int read(){
    	int x=0,f=1;char ch=getchar();
    	while (ch<'0' || ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    	while (ch>='0' && ch<='9'){x=x*10+ch-48;ch=getchar();}
    	return x*f;
    }
    
    ll readll(){
    	ll x=0,f=1;char ch=getchar();
    	while (ch<'0' || ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    	while (ch>='0' && ch<='9'){x=x*10+ch-48;ch=getchar();}
    	return x*f;
    }
    
    int main(){
        cin>>n>>m>>s>>t;
        cnt=0;
        for (int i=1;i<=n;i++) head[i] = -1;
        for (int i=1;i<=m;i++){
            int u,v;
            ll c;
            u=read();v=read();c=readll();
            add(u,v,c);add(v,u,0);
        }
        EK();
        printf("%lld
    ",maxflow);
        return 0;
    }
    
    你将不再是道具,而是成为人如其名的人
  • 相关阅读:
    为什么前后端分离了,你比从前更痛苦?
    HTML命名规范
    常用一屏自适应布局(一)
    CSS-网站导航栏标题之间的分隔符
    React-setState源码的理解
    如何在React-Native上使用Typescript
    immutable-js基础
    stylus 移动端边框1像素问题解决方案
    react native ts环境搭建
    react结合ts与mobx环境搭建步骤详解
  • 原文地址:https://www.cnblogs.com/wsl-lld/p/13393583.html
Copyright © 2020-2023  润新知