题目链接

题意 : 中文题请点链接,挺复杂的...

分析 : 乍一看是个最短路,实际就真的是个最短路。如果没有 “ 在有多条最短路径的时候输出换乘次数最少的” 这一条件的约束,那么这题就是直接建图然后跑个 Dij 就行了,那有了这个约束条件还是要大胆的向最短路思路靠,题目既然需要换乘次数少的,那么我们在进行最短路松弛操作的时候,面对松弛过后最短路径相等的情况就要分开讨论,这时候为了方法取最优值,需要多记录一个信息 ==> 跑到当前点时候换乘次数是多少次,开个数组来记录就行了,其他的还是按最短路来跑。这题就是编码烦了点,不对!是非常烦_(:3 」∠)_

#include<bits/stdc++.h>
using namespace std;
;
]; ///向前星存图
struct NODE{ ///跑DIJ时塞在优先队列的结构体
    int v, Pre_v, TransferCnt, Dist; ///当前是哪个点、其前一个点是什么、换乘次数、源点到此点的最短距离

    NODE(int V, int D, int Pv, int TCnt):v(V),Dist(D),Pre_v(Pv),TransferCnt(TCnt){};
    bool operator < (const NODE &rhs) const{
        if(this->Dist == rhs.Dist){ ///最短距离相等应当选择换乘次数小的
            return this->TransferCnt > rhs.TransferCnt; ///由于是优先队列、重载小于号需要注意方向....
        }else{
            return this->Dist > rhs.Dist;
        }
    };
};

int cnt; ///边数量
int Head[maxn]; ///邻接表头
int Pre[maxn]; ///答案路径中每个点的前驱、便于恢复路径
int Dis[maxn]; ///记录Dij中源点到其他点的最短路距离
int TransNum[maxn]; ///到达这个点的时候换乘了多少次
int Line[maxn][maxn]; ///记录路线信息
]; ///存储答案路径
bool vis[maxn]; ///DIJ中的标记数组

inline void init() ///初始化表头和计数变量
{
    memset(Head, -, sizeof(Head));
    cnt = ;
}

inline void AddEdge(int from, int to) ///加边函数
{
    Edge[cnt].v = to;
    Edge[cnt].nxt = Head[from];
    Head[from] = cnt++;
}

inline void Run_Dijkstra(int st, int en)
{
    memset(vis, false, sizeof(vis));
    memset(Dis, 0x3f3f3f3f, sizeof(Dis));
    memset(TransNum, , sizeof(TransNum));
    priority_queue<NODE> que; while(!que.empty()) que.pop();
    Dis[st] = ;
    que.push(NODE(st,,,));

    while(!que.empty()){
        NODE T = que.top(); que.pop();

        if(vis[T.v]) continue;
        else vis[T.v] = true;

        ; i=Edge[i].nxt){
            int Eiv = Edge[i].v;
            ){ ///满足松弛条件

                Dis[Eiv] = Dis[T.v] + ;
                 : T.TransferCnt + (Line[T.v][Eiv] != Line[T.Pre_v][T.v])); ///计算新的换乘次数

                que.push(NODE(Eiv, Dis[Eiv], T.v, NewTrans));
                Pre[Eiv] = T.v; ///记录前驱、便于恢复路径
                TransNum[Eiv] = NewTrans; ///记录当前点的换乘次数
            }
             && ///最短距离与松弛后相等则接下来比较换乘次数
                    TransNum[Eiv] > T.TransferCnt + (Line[T.v][Eiv] != Line[T.Pre_v][T.v])){

                que.push(NODE(Eiv, Dis[Eiv], T.v, T.TransferCnt + (Line[T.v][Eiv] != Line[T.Pre_v][T.v])));
                Pre[Eiv] = T.v; ///改变前驱
                TransNum[Eiv] = T.TransferCnt + (Line[T.v][Eiv] != Line[T.Pre_v][T.v]); ///更新换乘次数
            }
        }
    }

    if(Dis[en] == 0x3f3f3f3f){ ///不可达、输出 No Solution
        puts("Sorry, no line is available.");
        return ;
    }else{
        ; ///记录路径中节点个数
        int now = en; ///由于记录的是前驱、所以从终点开始恢复路径
        int StNext;
        path[top++] = en;
        while(now != st){
            int temp = Pre[now];
            if(temp==st) StNext = now; ///记录起点的后继 ==> 我接下来的输出满足题目所需的答案有需要
            path[top++] = temp;
            now = temp;
        }

        printf("%d\n", Dis[en]); ///先输出最短距离
        int CurLine = Line[st][StNext]; ///从起点开始记录当前所在的铁路编号
        int CurPoint = st; ///当前的点
        ; i>=; i--){
            ]] == CurLine) continue; ///如果下一个点和仍然在和之前一样的铁路编号则说明不是换乘点
            else{
                printf("Go by the line of company #%d from %04d to %04d.\n",CurLine, CurPoint, path[i]); ///输出格式需要注意....
                ///printf("Go by the line of company #%d from %d to %d.\n", CurLine, CurPoint, path[i]); ///!!!错误的输出格式!!!
                CurPoint = path[i]; ///更新 CurPoint、CurLine
                CurLine = Line[path[i]][path[i-]];
            }
        }
        printf(]);
       ///printf("Go by the line of company #%d from %d to %d.\n", CurLine, CurPoint, path[0]); ///!!!错误的输出格式!!!
    }
}

int main(void)
{
    init();
    int n;
    scanf("%d", &n);
    ; i<=n; i++){
        int num, A, B;
        scanf("%d %d", &num, &A);
        ; j<num; j++){
            scanf("%d", &B);
            AddEdge(A, B);
            AddEdge(B, A);
            Line[A][B] = Line[B][A] = i;
            A = B;
        }
    }

    int Query;
    scanf("%d", &Query);
    while(Query--){
        int A, B;
        scanf("%d %d", &A, &B);
        Run_Dijkstra(A, B);
    }
    ;
}

浙大PAT CCCC L3-014 周游世界 ( 最短路变形 )的更多相关文章

  1. 浙大PAT CCCC L3-001 凑零钱 ( 0/1背包 && 路径记录 )

    题目链接 分析 : 就是一个 0/1 背包,但是需要记录具体状态的转移情况 这个可以想象成一个状态转移图,然后实际就是记录路径 将状态看成点然后转移看成边,最后输出字典序最小的路径 这里有一个很巧妙的 ...

  2. 浙大PAT CCCC L3-013 非常弹的球 ( 高中物理题 )

    题目链接 题意 : 刚上高一的森森为了学好物理,买了一个“非常弹”的球.虽然说是非常弹的球,其实也就是一般的弹力球而已.森森玩了一会儿弹力球后突然想到,假如他在地上用力弹球,球最远能弹到多远去呢?他不 ...

  3. 浙大PAT CCCC L3-015 球队“食物链” ( 搜索 && 剪枝 )

    题目链接 题意 : 有 n 个球队,给出主客场胜负图,找出一个序列 1.2.3..... 使得 1 战胜过 2 .2 战胜过 3.3 战胜过 4..... n 战胜过 1 ( 这个序列是 1~n 的其 ...

  4. 天梯赛 大区赛 L3-014.周游世界 (Dijkstra)

    L3-014. 周游世界 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 周游世界是件浪漫事,但规划旅行路线就不一定了-- 全世 ...

  5. L3-014 周游世界 (30 分)

    周游世界是件浪漫事,但规划旅行路线就不一定了…… 全世界有成千上万条航线.铁路线.大巴线,令人眼花缭乱.所以旅行社会选择部分运输公司组成联盟,每家公司提供一条线路,然后帮助客户规划由联盟内企业支持的旅 ...

  6. 团体程序设计天梯赛(CCCC) L3014 周游世界 BFS证明

    团体程序设计天梯赛代码.体现代码技巧,比赛技巧.  https://github.com/congmingyige/cccc_code

  7. A题进行时--浙大PAT 1001-1010

    pat链接:http://pat.zju.edu.cn 1 #include<stdio.h> 2 int main(){ 3 int a,b; 4 int c; 5 while(scan ...

  8. 浙大pat 1035题解

    1035. Password (20) 时间限制 400 ms 内存限制 32000 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue To prepare f ...

  9. 浙大pat 1025题解

    1025. PAT Ranking (25) 时间限制 200 ms 内存限制 32000 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue Programmi ...

随机推荐

  1. 【转载】linux下如何使用sftp命令

    原文地址:http://www.cnblogs.com/chen1987lei/archive/2010/11/26/1888391.html sftp 是一个交互式文件传输程式.它类似于 ftp, ...

  2. Canvas入门02-绘制直线

    主要使用的API有: context.moveTo(x,y) 声明线的起始坐标 context.lineTo(x,y) 声明线的下一个坐标 context.fillStyle  声明线的填充颜色 co ...

  3. BindWeb - Bind智能DNS管理系统介绍

    2019-05-08 演示网站: https://bindw.cdneks.com demo/demo 2018-11-27 修改部署架构,取消网络共享存储设备,在每台BIND服务器启用NFS4并仅向 ...

  4. nrm安装与配置

    nrm安装与配置:https://blog.csdn.net/anway12138/article/details/79455224

  5. Eureka 源码分析之 Eureka Server

    文章首发于公众号<程序员果果> 地址 : https://mp.weixin.qq.com/s/FfJrAGQuHyVrsedtbr0Ihw 简介 上一篇文章<Eureka 源码分析 ...

  6. 2019 CSP-S初赛游记

    2019-10-19 ——这个注定要被载入史册的日子 作为一名初中生,和lpy大佬一同参加提高组的比赛,而今年普及组和提高组的时间竟然不一样,于是——凌晨六点半,来到了pdyz和高中生一起坐车去. 高 ...

  7. faker数据填充详解

    安装 在laravel中已经自动集成,无需手动安装.如需在其他地方使用,可使用以下命令进行安装. composer require fzaninotto/faker 为Faker指定中文支持 可通过在 ...

  8. 数塔 Medium

    Summer is coming! It's time for Iahub and Iahubina to work out, as they both want to look hot at the ...

  9. 数据库允许空值(null),往往是悲剧的开始 (转)

    数据库字段允许空值,会遇到一些问题,此处包含的一些知识点,和大家聊一聊. 数据准备: create table user ( id int, name varchar(20), index(id) ) ...

  10. 线程中断:Thread类中interrupt()、interrupted()和 isInterrupted()方法详解

    首先看看官方说明: interrupt()方法 其作用是中断此线程(此线程不一定是当前线程,而是指调用该方法的Thread实例所代表的线程),但实际上只是给线程设置一个中断标志,线程仍会继续运行. i ...