• [UVA 11374]Airport Express


    这个题有两种路径,普通线和商务线。而且告诉我们商务线就只能用一次,那很显然枚举就行。枚举每一条商务线,看能否更新最短路就行。我们从起点终点分别出发跑最短路,如果起点到商务线一个端点的最短距离加上终点到商务线另一个端点最短距离再加上商务线距离之和可以更新现有最短路,则更新最短路。枚举下去就行,复杂度为O(t * k * mlogn),其中t为数据组数,k为商务线数,m、n分别为边数和点数。

    参考代码:

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #include<iostream>
    #include<stack>
    #define inf 1e9
    using namespace std;
    #define N 510
    #define M 2010
    int head[N],nxt[M],to[M],val[M],dis[M],dist[M],path[N],patht[N];
    int n,m,k,s,t,cnt;
    void add(int u,int v,int w)
    {
        nxt[++cnt] = head[u];
        head[u] = cnt;
        val[cnt] = w;
        to[cnt] = v;
    }
    struct node
    {
        int u,dis;
        bool operator < (const node &a) const
        {
            return dis > a.dis;
        }
    }top,qwq;
    void dijkstra(int str)
    {
        priority_queue<node>q;
        memset(path,0,sizeof(path));
        for(int i = 1;i <= n;i++) dis[i] = inf;
        dis[str] = 0;
        top.u = str;
        top.dis = 0;
        q.push(top);
        while(!q.empty())
        {
            top = q.top();
            q.pop();
            int u = top.u;
            for(int i = head[u];i;i = nxt[i])
            {
                int v = to[i];
                if(dis[v] > dis[u] + val[i])
                {
                    path[v] = u;
                    dis[v] = dis[u] + val[i];
                    qwq.u = v;
                    qwq.dis = dis[v];
                    q.push(qwq);
                }
            }
        }
    }
    void dfs(int u)//枚举前驱输出路径
    {
        if(u == s)
        {
            printf("%d",u);
            return;
        }
        dfs(path[u]);
        printf(" %d",u);
    }
    void dfst(int u)
    {
        printf(" %d",u);
        if(u == t) return;
        dfst(patht[u]);
    }
    int main()
    {
        int flag = 0;
        while(scanf("%d %d %d",&n,&s,&t) != EOF)
        {
            if(flag) printf("
    ");
            memset(head,0,sizeof(head));
            cnt = 0;
            scanf("%d",&m);
            for(int i = 1;i <= m;i++)
            {
                int x,y,z;
                scanf("%d %d %d",&x,&y,&z);
                add(x,y,z);
                add(y,x,z);
            }
            dijkstra(t);
            for(int i = 1;i <= n;i++) 
            {
                dist[i] = dis[i];
                patht[i] = path[i];
            }
            dijkstra(s);
            scanf("%d",&k);
            int ss = 0,tt = 0,ans = dis[t];
            while(k--)
            {
                int u,v,w;
                scanf("%d %d %d",&u,&v,&w);
                if(dis[u] + dist[v] + w < ans)
                {
                    ans = dis[u] + dist[v] + w;
                    ss = u;
                    tt = v;
                }
                if(dist[u] + dis[v] + w < ans)
                {
                    ans = dist[u] + dis[v] + w;
                    ss = v;
                    tt = u;
                }
            }
            if(ss != 0)//看最短路是否被更新
            {
                dfs(ss);
                dfst(tt);
                printf("
    %d
    %d
    ",ss,ans);
            }
            else
            {
                dfs(t);
                printf("
    Ticket Not Used
    %d
    ",ans);
            }
            flag++;
        }
    }
  • 相关阅读:
    subprocess
    bytes(str_, encoding="utf8")
    按文件生成时间 排序 批量与生成同步上传文件
    async
    http trigger 事件源是事件的生产者,函数是事件的处理者
    分片上传
    使用 FFmpeg 处理高质量 GIF 图片
    兴趣 主题 字段 二值化 多值并列属性 拆分 二值化
    打开 回收站
    shell如何查看单个或多个文件的行数或总行数
  • 原文地址:https://www.cnblogs.com/lijilai-oi/p/10725293.html
Copyright © 2020-2023  润新知