zoukankan      html  css  js  c++  java
  • 网络流算法

    Dinic算法

    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<queue>
    #include<algorithm>
    #include<vector>
    using namespace std;
    const int INF=1e9+7;
    const int maxn=205;
    int N,M,S,T;
    struct edge
    {
        int u,v,cap,flow;
        edge(int u=0,int v=0,int cap=0,int flow=0)
        :u(u),v(v),cap(cap),flow(flow){}
    }E[maxn*maxn];
    int eid; //要初置为0
    vector<int> G[maxn];
    void init()
    {
        eid=0;
        for(int i=0;i<maxn;i++) G[i].clear();
    }
    void AddEdge(int u,int v,int cap)
    {
        E[eid]=edge(u,v,cap,0);
        G[u].push_back(eid++);
        E[eid]=edge(v,u,0,0);
        G[v].push_back(eid++);
    }
    bool vis[maxn];
    int d[maxn],cur[maxn];
    queue<int> que;
    bool BFS()
    {
        memset(vis,false,sizeof(vis));
        while(!que.empty()) que.pop();
        vis[S]=true;
        d[S]=0;
        que.push(S);
        while(!que.empty())
        {
            int u=que.front();  que.pop();
            int Size=G[u].size();
            for(int i=0;i<Size;i++)
            {
                int id=G[u][i];
                edge& e=E[id];
                int v=e.v;
                if(!vis[v]&&e.cap>e.flow)
                {
                    vis[v]=true;
                    d[v]=d[u]+1;
                    que.push(v);
                }
            }
        }
        return vis[T];
    }
    int DFS(int u,int a)
    {
        if(u==T||a==0) return a;
        int ret=0,f;
        int Size=G[u].size();
        for(int& i=cur[u];i<Size;i++)
        {
            int id=G[u][i];
            edge& e=E[id];
            int v=e.v;
            if(d[u]+1==d[v]&&(f=DFS(v,min(a,e.cap-e.flow)))>0)
            {
                ret+=f;
                e.flow+=f;
                E[id^1].flow-=f;
                a-=f;
                if(a==0) break;
            }
        }
        return ret;
    }
    int MaxFlow(int s,int t)
    {
        S=s; T=t;
        int ret=0;
        while(BFS())
        {
            memset(cur,false,sizeof(cur));
            ret+=DFS(S,INF);
        }
        return ret;
    }
    View Code

    EK算法

    struct edge
    {
        int from,to,cap,flow;
        edge(int from=0,int to=0,int cap=0,int flow=0)
        :from(from),to(to),cap(cap),flow(flow){}
    };
    vector<edge> save;
    vector<int> G[105];
    void addedge(int from,int to,int cap,int flow)
    {
        save.push_back(edge(from,to,cap,flow));
        save.push_back(edge(to,from,0,flow));
        int id=save.size();
        G[from].push_back(id-2);
        G[to].push_back(id-1);
    }
    int add[105],fa[105];
    int MaxFlow(int be,int en)
    {
        int ret=0;
        while(true)
        {
            memset(add,0,sizeof(add));
            queue<int> que;
            que.push(be);
            add[be]=INF;
            while(!que.empty())
            {
                int from=que.front();  que.pop();
                for(int i=0;i<G[from].size();i++)
                {
                    edge e=save[G[from][i]];
                    int to=e.to,cap=e.cap,flow=e.flow;
                    if(!add[to]&&cap>flow)
                    {
                        fa[to]=G[from][i];
                        add[to]=min(add[from],cap-flow);
                        que.push(to);
                    }
                }
                if(add[en])  break;
            }
            if(!add[en])  break;
            for(int st=en;st!=be;st=save[fa[st]].from)
            {
                save[fa[st]].flow+=add[en];
                save[fa[st]^1].flow-=add[en];
            }
            ret+=add[en];
        }
        return ret;
    }
    View Code

    最小费最大流算法

    struct edge
    {
        int u,v;
        int cap,flow,cost;
        edge(int u=0,int v=0,int cap=0,int flow=0,int cost=0)
        :u(u),v(v),cap(cap),flow(flow),cost(cost){}
    }save[4*maxn*maxn];
    struct MFMC
    {
        int n,edge_num;
        vector<int> G[maxn];
        void init(int nn)
        {
            n=nn;
            edge_num=0;
            for(int i=0;i<=n;i++) G[i].clear();
        }
        void addedge(int u,int v,int cap,int cost)
        {
            int a=edge_num++;
            int b=edge_num++;
            save[a]=edge(u,v,cap,0,cost);
            save[b]=edge(v,u,0,0,-cost);
            G[u].push_back(a);
            G[v].push_back(b);
        }
        int add[maxn],C[maxn];
        int fa[maxn];
        bool inq[maxn];
        void clr(int s)
        {
            for(int i=0;i<=n;i++) add[i]=0,inq[i]=false,C[i]=INF;
            add[s]=INF; inq[s]=true; C[s]=0;
            fa[s]=0;
        }
        int solve(int s,int t)
        {
            int cnt=0,ret=0;
            while(true)
            {
                clr(s);
                queue<int> que;
                que.push(s);
                while(!que.empty())
                {
                    int u=que.front();  que.pop();
                    inq[u]=false;
                    int Size=G[u].size();
                    for(int i=0;i<Size;i++)
                    {
                        int edge_id=G[u][i];
                        edge& e=save[edge_id];
                        int v=e.v;
                        int cap=e.cap,flow=e.flow,cost=e.cost;
                        if(cap>flow&&C[v]>C[u]+cost)
                        {
                            C[v]=C[u]+cost;
                            fa[v]=edge_id;
                            add[v]=min(add[u],cap-flow);
                            if(!inq[v]){ inq[v]=true; que.push(v); }
                        }
                    }
                }
                if(!add[t])  break;
                cnt+=add[t];
                ret+=add[t]*C[t];
                for(int st=t;st!=s;st=save[fa[st]].u)
                {
                    int a=fa[st],b=fa[st]^1;
                    save[a].flow+=add[t];
                    save[b].flow-=add[t];
                }
           }
           return ret;
        }
    };
    View Code
  • 相关阅读:
    机器学习:SVM(核函数、高斯核函数RBF)
    机器学习:SVM(非线性数据分类:SVM中使用多项式特征和核函数SVC)
    LeetCode566. Reshape the Matrix
    LeetCode 128. Longest Consecutive Sequence
    # 线程安全 & 线程安全函数 & 线程不安全函数
    Linux进程状态
    C++ 4种强制类型转换
    TCP超时重传、滑动窗口、拥塞控制、快重传和快恢复
    LeetCode 69. Sqrt(x)
    LeetCode543. Diameter of Binary Tree
  • 原文地址:https://www.cnblogs.com/wust-ouyangli/p/5706345.html
Copyright © 2011-2022 走看看