题目链接

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

分析 : 乍一看是个最短路,实际就真的是个最短路。如果没有 “ 在有多条最短路径的时候输出换乘次数最少的” 这一条件的约束,那么这题就是直接建图然后跑个 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. CSS3—— 分页 框大小 弹性盒子 多媒体查询 多媒体查询实例

    分页 网站有很多个页面,就需要使用分页来为每个页面做导航 点击及鼠标悬停分页样式 圆角样式 悬停过度效果 带边框的分页 分页间隔 分页字体大小 居中分页 面包屑导航 框大小 box-sizing 属性 ...

  2. unlink- ctf-stkof

    stkof 程序下载:https://pan.baidu.com/s/1_dcm8OFjhKbKYWa3WBtAiQ 提取码:pkyb unlink 基础操作 # define unlink #def ...

  3. Android - Android 面试题集 -- Android 部分答案

    2.1 Activity1.Activity是什么?Activity是Android的四大组件之一.是用户操作的可视化界面:它为用户提供了一个完成操作指令的窗口.当我们创建完毕Activity之后,需 ...

  4. 解决react项目中跨域和axios封装使用

    最新几天学了一下react,发现了几个问题,估计新入坑的同学们也会遇到,下面我先列出来几点 1.请求跨域问题 2.如何发起请求 3.axios的简单封装 全局安装create-react-app脚手架 ...

  5. Spring Boot 为什么这么火?(二)

    Spring Boot 的火 网上连载了 Spring Boot 系列文章,没想到这一开始便与 Spring Boot 深度结缘. 技术社区 Spring Boot 的文章越来越多:Spring Bo ...

  6. Hive调优参数配置

    Hive进行大数据处理的过程中经常遇到一个任务跑几个小时或者内存溢出等问题,平时会任务执行的遇到的问题 进行参数的调整配置,收集整理的配置参考如下: set dfs.namenode.handler. ...

  7. Tarjan水题系列(3):HNOI2006 潘多拉的魔盒

    题目: 链接 大意: 盒子与盒子之间的关系构成一个有向图 求图上包含节点数最多的路径的节点数 思路: 有向图上求包含节点数最多的路径的节点数 可直接使用tarjan缩点后拓扑dp求得 在此不赘述 此题 ...

  8. Codeforces Round #503 (by SIS, Div. 2) E. Sergey's problem

    E. Sergey's problem [题目描述] 给出一个n个点m条边的有向图,需要找到一个集合使得1.集合中的各点之间无无边相连2.集合外的点到集合内的点的最小距离小于等于2. [算法] 官方题 ...

  9. Codeforces - 1096G - Lucky Tickets - NTT

    https://codeforc.es/contest/1096/problem/G 把数组分成前后两半,那么前半部分的各个值的表示方案的平方的和就是答案. 这些数组好像可以dp出来. 一开始设dp[ ...

  10. HTML-美化

    1.美化文本 1.1第一部分 font-size:字体大小,常用em.px.%.rem作单位,预设值small.large.medium,可继承, font-weight:加粗字体,属性为bold,加 ...