zoukankan      html  css  js  c++  java
  • 图论:网络流最大流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;
    }
    
    你将不再是道具,而是成为人如其名的人
  • 相关阅读:
    php+GTK2 学习第二篇
    PHPMailer + qq邮箱 实现邮件发送
    HTTP状态码200、301、403、404、500等(转)
    LNMP环境搭建(转载)
    PHP+GTK2 初体验,简单计算器客户端
    mysql 用户权限管理(转)
    提高php执行效率的10条编程习惯(转)
    添加php拓展(以phppcntl及phpredis及phppcntl为例)
    centos7 &后台运行 受终端关闭影响问题
    sklearn学习笔记之简单线性回归
  • 原文地址:https://www.cnblogs.com/wsl-lld/p/13393583.html
Copyright © 2011-2022 走看看