zoukankan      html  css  js  c++  java
  • [网络流24题#11] 航空路线 [网络流,最大权值最大流]

    只需要把费用流的Spfa中的小于号改一下就好了,对于题目中要求要飞过去在飞回来,只需要一律把边的方向定为从顶点编号较小的向顶点编号较大的,把顶点1和n的边的容量定为2,其余边为1即可。

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <ctime>
    #include <map>
    #include <string>
    #include <queue>
    
    using namespace std;
    
    template<const int _n,const int _m>
    struct Edge
    {
        struct Edge_base { int    to,next,w,c; }e[_m];
        int    cnt,p[_n];
        Edge() { clear(); }
        int    start(const int x) { return p[x]; }
        void    insert(const int x,const int y,const int z,const int zz)
        { e[++cnt].to=y; e[cnt].next=p[x]; e[cnt].w=z; e[cnt].c=zz; p[x]=cnt; return ; }
        void    clear() { cnt=1,memset(p,0,sizeof(p)); }
        Edge_base&    operator[](const int x) { return e[x]; }
    };
    
    Edge<310,210000>    e;
    map<string,int>        Map;
    int    n,m,Cost,SSS,TTT;
    int    Dis[310],cur[310];
    bool    visited[310];
    
    bool    Spfa(const int S)
    {
        int    i,t,temp;
        queue<int>    Q;
        memset(Dis,0x80,sizeof(Dis));
        memset(visited,0,sizeof(visited));
        Dis[S]=0;
        visited[S]=true;
        Q.push(S);
        while(!Q.empty())
        {
            t=Q.front(),Q.pop();visited[t]=false;
            for(i=e.start(t);i;i=e[i].next)
            {
                temp=e[i].to;
                if(Dis[temp]<Dis[t]+e[i].c && e[i].w)
                {
                    Dis[temp]=Dis[t]+e[i].c;
                    if(!visited[temp])
                    {
                        Q.push(temp);
                        visited[temp]=true;
                    }
                }
            }
        }
        return Dis[TTT]!=(int)0x80808080;
    }
    
    int    Dfs(const int S,const int bk)
    {
        if(S==TTT)return bk;
        int    rest=bk;
        visited[S]=true;
        for(int &i=cur[S];i;i=e[i].next)
        {
            if(Dis[S]+e[i].c==Dis[e[i].to] && e[i].w && !visited[e[i].to])
            {
                int    flow=Dfs(e[i].to,min(rest,e[i].w));
                Cost+=flow*e[i].c;
                e[i].w-=flow;
                e[i^1].w+=flow;
                if((rest-=flow)<=0)break;
            }
        }
        visited[S]=false;
        if(bk==rest)Dis[S]=0x3f3f3f3f;
        return bk-rest;
    }
    
    int    Dinic()
    {
        int    flow=0;
        while(Spfa(SSS))
        {
            memcpy(cur,e.p,sizeof(cur));
            flow+=Dfs(SSS,0x3f3f3f3f);
        }
        return Cost;
    }
    
    int main()
    {
        freopen("in","r",stdin);
        freopen("out","w",stdout);
        int    i;
        string    str,str1,str2;
    
        cin >> n >> m;
        SSS=n<<1|1,TTT=SSS+1;
        for(i=1;i<=n;++i)
        {
            cin >> str;
            Map[str]=i;
            e.insert(i+n,i,1,0);
            e.insert(i,i+n,0,0);
        }
        
        e.insert(SSS,1,2,0);
        e.insert(1,SSS,0,0);
        e.insert(n+n,TTT,2,0);
        e.insert(TTT,n+n,0,0);
        
        for(i=1;i<=m;++i)
        {
            cin >> str1 >> str2;
            int x=Map[str1],y=Map[str2];
            if(x>y)swap(x,y);
            e.insert(x,y+n,x!=1?x!=n?1:2:2,1);
            e.insert(y+n,x,0,-1);
        }
    
        int    temp=Dinic();
        if(temp)cout << temp << endl;
        else    cout << "No Solution!" << endl;
    
        return 0;
    }
  • 相关阅读:
    受限玻尔兹曼机 视频
    android textview空格占位符以及一些其他占位符汇总
    几种常见的Preference总结
    Android著名开源库
    Android 常用开源库总结(持续更新)
    2019最新Android常用开源库总结(附带github链接)
    Android gradle用exclude排除引用包中的dependency引用
    Gradle3.0新指令api、provided、implementation等对比
    jar包下载网站
    mac环境下Android 反编译
  • 原文地址:https://www.cnblogs.com/Gster/p/4996883.html
Copyright © 2011-2022 走看看