• 网络流24题-航空路线问题


    航空路线问题

    时空限制1000ms / 128MB

    题目描述

    给定一张航空图,图中顶点代表城市,边代表 2 城市间的直通航线。现要求找出一条满足下述限制条件的且途经城市最多的旅行路线。

    (1)从最西端城市出发,单向从西向东途经若干城市到达最东端城市,然后再单向从东向西飞回起点(可途经若干城市)。

    (2)除起点城市外,任何城市只能访问 1 次。

    对于给定的航空图,试设计一个算法找出一条满足要求的最佳航空旅行路线。

    输入输出格式

    输入格式:

    第 1 行有 2 个正整数 N 和 V,N 表示城市数,N<100,V 表示直飞航线数。

    接下来的 N 行中每一行是一个城市名,可乘飞机访问这些城市。城市名出现的顺序是从西向东。也就是说,设 i,j 是城市表列中城市出现的顺序,当 i>j 时,表示城市 i 在城市 j 的东边,而且不会有 2 个城市在同一条经线上。城市名是一个长度不超过15 的字符串,串中的字符可以是字母或阿拉伯数字。例如,AGR34 或 BEL4。

    再接下来的 V 行中,每行有 2 个城市名,中间用空格隔开,如 city1 city2 表示 city1到 city2 有一条直通航线,从 city2 到 city1 也有一条直通航线。

    输出格式:

    件第 1 行是旅行路线中所访问的城市总数 M。 接下来的 M+1 行是旅行路线的城市名,每行写 1 个城市名。首先是出发城市名,然后按访问顺序列出其它城市名。 注意,最后 1 行(终点城市)的城市名必然是出发城市名。如果问题无解,则输出“No Solution!”。

    输入输出样例

    输入样例: 
    8 9
    Vancouver
    Yellowknife
    Edmonton
    Calgary
    Winnipeg
    Toronto
    Montreal
    Halifax
    Vancouver Edmonton
    Vancouver Calgary
    Calgary Winnipeg
    Winnipeg Toronto
    Toronto Halifax
    Montreal Halifax
    Edmonton Montreal
    Edmonton Yellowknife
    Edmonton Calgary
    输出样例: 
    7
    Vancouver
    Edmonton
    Montreal
    Halifax
    Toronto
    Winnipeg
    Calgary
    Vancouver 

    说明

    题目链接:https://www.luogu.org/problemnew/show/P2770


    最大权不相交路径。一开始我没想到竟然可以看成从左端点开始的两条不相交路径,瞎搞了好久。。。 
    #include<bits/stdc++.h>
    #define INF LLONG_MAX/2
    #define N 205
    using namespace std;
    
    struct ss
    {
        int u,v,next;
        long long flow,cost;
    };
    
    ss edg[N*N];
    int head[N],now_edge=0;
    
    void addedge(int u,int v,long long flow,long long cost)
    {
        cost=-cost;
        edg[now_edge]=(ss){u,v,head[u],flow,cost};
        head[u]=now_edge++;
        edg[now_edge]=(ss){v,u,head[v],0,-cost};
        head[v]=now_edge++;
    }
    
    int spfa(int s,int t,long long &flow,long long &cost)
    {
        int vis[N]={0};
        vis[s]=1;
        queue<int>q;
        q.push(s);
        long long dis[N];
        for(int i=0;i<N;i++)dis[i]=INF;
        dis[s]=0;
        int pre[N]={0};
        long long addflow[N]={0};
        addflow[s]=INF;
        
        while(!q.empty())
        {
            int now=q.front();
            q.pop();
            vis[now]=0;
            
            for(int i=head[now];i!=-1;i=edg[i].next)
            {
                ss e=edg[i];
                if(e.flow>0&&dis[e.v]>dis[now]+e.cost)
                {
                    dis[e.v]=dis[now]+e.cost;
                    pre[e.v]=i;
                    addflow[e.v]=min(e.flow,addflow[now]);
                    if(!vis[e.v])
                    {
                        q.push(e.v);
                        vis[e.v]=1;
                    }
                }
            }
        }
        
        if(dis[t]==INF)return 0;
        
        flow+=addflow[t];
        cost+=addflow[t]*dis[t];
        
        int now=t;
        while(now!=s)
        {
            edg[pre[now]].flow-=addflow[t];
            edg[pre[now]^1].flow+=addflow[t];
            now=edg[pre[now]].u;
        }
        return 1;
        
    }
    
    void mcmf(int s,int t,long long &flow,long long &cost)
    {
        while(spfa(s,t,flow,cost));
    }
    
    void init()
    {
        now_edge=0;
        memset(head,-1,sizeof(head));
    }
    
    map<string,int>Map1;
    map<int,string>Map2;
    
    vector<int>ans;
    int n;
    
    void dfs(int x)
    {
        if(x==n)return;
        int u=x*2;
        for(int i=head[u];i!=-1;i=edg[i].next)
        {
            if(edg[i^1].flow&&edg[i].v!=u-1)
            {
                edg[i^1].flow--;
                ans.push_back(edg[i].v/2+1);
                dfs(edg[i].v/2+1);
                return;
                
            }
        }
    }
    
    int main()
    {
        init();
        int m;
        scanf("%d %d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            string a;
            cin>>a;
            Map1.insert(pair<string,int>(a,i));
            Map2.insert(pair<int,string>(i,a));
        }
        int s=2*n+1,t=s+1;
        
        while(m--)
        {
            string a,b;
            cin>>a>>b;
            int u=min(Map1[a],Map1[b]),v=max(Map1[a],Map1[b]);
            addedge(u*2,v*2-1,INF,0);
        }
        
        for(int i=2;i<n;i++)addedge(i*2-1,i*2,1,1);
        addedge(1,2,2,1);
        addedge(2*n-1,2*n,2,1);
        addedge(s,1,2,0);
        addedge(2*n,t,INF,0);
        
        long long flow=0,cost=0;
        mcmf(s,t,flow,cost);
        
        if(flow<2)
        {
            printf("No Solution!
    ");
            return 0;
        }
        
        printf("%lld
    ",-cost-2);
        
        dfs(1);
        cout<<Map2[1]<<endl;
        for(int i=0;i<ans.size();i++)cout<<Map2[ans[i]]<<endl;
        ans.clear();
        dfs(1);
        for(int i=ans.size()-2;i>=0;i--)cout<<Map2[ans[i]]<<endl;
        cout<<Map2[1]<<endl;
        return 0;
        
    }
    View Code
  • 相关阅读:
    【转】深入理解Java内存模型(二)——重排序
    mysql 查询表字段信息(字段名、描述、类型、长度)
    SQL-Server随机日期值
    浏览器一直不停的异步请求(环境:vs.net mvc)
    asp.net mvc 默认首页设置静态文件
    字符串转json对象 SyntaxError: missing ; before statement
    SQL Server 自增标识位插入显示值
    c# 去除字符串中的换行符 " "
    处理SQL注入参考
    多线程简单应用示例
  • 原文地址:https://www.cnblogs.com/tian-luo/p/9726804.html
Copyright © 2020-2023  润新知