吝啬的国度

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 3
描述
在一个吝啬的国度里有N个城市,这N个城市间只有N-1条路把这个N个城市连接起来。现在,Tom在第S号城市,他有张该国地图,他想知道如果自己要去参观第T号城市,必须经过的前一个城市是几号城市(假设你不走重复的路)。

输入
第一行输入一个整数M表示测试数据共有M(1<=M<=5)组
每组测试数据的第一行输入一个正整数N(1<=N<=100000)和一个正整数S(1<=S<=100000),N表示城市的总个数,S表示参观者所在城市的编号
随后的N-1行,每行有两个正整数a,b(1<=a,b<=N),表示第a号城市和第b号城市之间有一条路连通。
输出
每组测试数据输N个正整数,其中,第i个数表示从S走到i号城市,必须要经过的上一个城市的编号。(其中i=S时,请输出-1)
样例输入
1
10 1
1 9
1 8
8 10
10 3
8 6
1 2
10 4
9 5
3 7
样例输出
-1 1 10 10 9 8 3 1 1 8

很明显,这个些城市和道路构成了一个极小连通子图,也就是生成树。而出发的城市S就相当于这棵树的树根,一种较易想到的解法就是从出发城市开始,对整个地图进行深度搜索,过程中记录下前一个城市的编号,如下,采用邻接表存储地图:

#include <stdio.h>struct node
{int num;node *next;
};struct data_type
{int priorCity;node *linkedCity;
}map[100005];void MyDelete(int cityNum)
{int i;node *p, *q;for (i = 1; i <= cityNum; i++){p = map[i].linkedCity;while (p != NULL){q = p->next;delete p;p = q;}}
}void Travel(int currentCity, int priorCity)
{map[currentCity].priorCity = priorCity;node *linkedCity = map[currentCity].linkedCity;while (linkedCity != NULL){if (map[linkedCity->num].priorCity == 0){Travel(linkedCity->num, currentCity);}linkedCity = linkedCity->next;}
}int main()
{int i, testNum, cityNum, startCity, cityA, cityB;node *p;scanf("%d", &testNum);while (testNum-- != 0){scanf("%d%d", &cityNum, &startCity);for (i = 0; i <= cityNum; i++){map[i].priorCity = 0;map[i].linkedCity = NULL;}for (i = 1; i < cityNum; i++){scanf("%d%d", &cityA, &cityB);p = new node;p->num = cityB;p->next = map[cityA].linkedCity;map[cityA].linkedCity = p;p = new node;p->num = cityA;p->next = map[cityB].linkedCity;map[cityB].linkedCity = p;}Travel(startCity, -1);for (i = 1; i < cityNum; i++){printf("%d ", map[i].priorCity);}printf("%d\n", map[i].priorCity);MyDelete(cityNum);}return 0;
}

上面的地图相当于一个无向图,而在深度搜索时,需要的只是一个以出发城市为中心,向四周辐射的有向图。改进算法是在输入数据的同时,就进行搜索地图,因为数据输入未完成,所以输入时得到的是一个子图,这个子图分两种情况,一种是子图中包含出发城市,子图是一个有向图,所以可以根据输入的两个城市哪一个离出发城市更近,确定结果;另一种子图中不包含出发城市,此时,无法确定哪个城市离出发城市更近,所以先用邻接表将这个无向子图存储起来,等到它与出发城市相连时,在对这个子图进行深度搜索。

例如输入的测试数据为:
10 1
8 10
10 3
3 7
10 4
1 9
1 8
8 6
1 2
9 5
则首先得到一个不包含出发城市的子图:

在输入数据1  8时之后,上面的子图与出发城市相连,图中红色方块代表出发城市,虚线箭头代表并未在邻接表中建立此联系:

#include <stdio.h>struct node
{int num;node *next;
};struct data_type
{int priorCity;bool start;node *linkedCity;
}map[100005];void InitMap(int cityNum, int startCity)
{int i;for (i = 0; i <= cityNum; i++){map[i].priorCity = 0;map[i].start = false;map[i].linkedCity = NULL;}map[startCity].start = true;map[startCity].priorCity = -1;
}void MyDelete(int cityNum)
{int i;node *p, *q;for (i = 1; i <= cityNum; i++){p = map[i].linkedCity;while (p != NULL){q = p->next;delete p;p = q;}}
}void Travel(int currentCity, int priorCity)
{map[currentCity].priorCity = priorCity;map[currentCity].start = true;node *linkedCity = map[currentCity].linkedCity;while (linkedCity != NULL){if (map[linkedCity->num].priorCity == 0){Travel(linkedCity->num, currentCity);}linkedCity = linkedCity->next;}
}int main()
{int i, testNum, cityNum, startCity, cityA, cityB;node *p;scanf("%d", &testNum);while (testNum-- != 0){scanf("%d%d", &cityNum, &startCity);InitMap(cityNum, startCity);for (i = 1; i < cityNum; i++){scanf("%d%d", &cityA, &cityB);if (map[cityA].start){if (map[cityB].linkedCity != NULL){Travel(cityB, cityA);}else{map[cityB].priorCity = cityA;map[cityB].start = true;}}else if (map[cityB].start){if (map[cityA].linkedCity != NULL){Travel(cityA, cityB);}else{map[cityA].priorCity = cityB;map[cityA].start = true;}}else{p = new node;p->num = cityB;p->next = map[cityA].linkedCity;map[cityA].linkedCity = p;p = new node;p->num = cityA;p->next = map[cityB].linkedCity;map[cityB].linkedCity = p;}}for (i = 1; i < cityNum; i++){printf("%d ", map[i].priorCity);}printf("%d\n", map[i].priorCity);MyDelete(cityNum);}return 0;
}

深度搜索时采用非递归函数:

struct
{int currentNum;int priorNum;
}stack[100005], *base = NULL, *top = NULL;void Travel(int currentCity, int priorCity)
{node *linkedCity = NULL;base = top = stack;top->currentNum = currentCity;top->priorNum = priorCity;top++;while (base != top){currentCity = (--top)->currentNum;priorCity = top->priorNum;map[currentCity].priorCity = priorCity;map[currentCity].start = true;linkedCity = map[currentCity].linkedCity;while (linkedCity != NULL){if (map[linkedCity->num].priorCity == 0){top->currentNum = linkedCity->num;top->priorNum = currentCity;top++;}linkedCity = linkedCity->next;}}
}

NYOJ 20 吝啬的国度相关推荐

  1. NYOJ 20 吝啬的国度(深搜)

    描述 在一个吝啬的国度里有N个城市,这N个城市间只有N-1条路把这个N个城市连接起来.现在,Tom在第S号城市,他有张该国地图,他想知道如果自己要去参观第T号城市,必须经过的前一个城市是几号城市(假设 ...

  2. NYOJ 20 吝啬的国度 广度优先搜索

    吝啬的国度 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 在一个吝啬的国度里有N个城市,这N个城市间只有N-1条路把这个N个城市连接起来.现在,Tom在第S号城市,他有 ...

  3. NYOJ 20 吝啬的国度 (搜索)

    吝啬的国度 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 在一个吝啬的国度里有N个城市,这N个城市间只有N-1条路把这个N个城市连接起来.现在,Tom在第S号城市,他有 ...

  4. NYOJ 20 吝啬的国度(深搜)

    描述 在一个吝啬的国度里有N个城市,这N个城市间只有N-1条路把这个N个城市连接起来.现在,Tom在第S号城市,他有张该国地图,他想知道如果自己要去参观第T号城市,必须经过的前一个城市是几号城市(假设 ...

  5. NYOJ 20 吝啬的国度 续

    还是<吝啬的国度>,研读了别人的较为高效的代码,无论是时间开销,还是空间开销都要小很多啊,截图为证: 我的所有运行: 52ms的是我参照别人的写的代码,时间开销比我的小将近一半,内存开销仅 ...

  6. 《图论》— NYOJ 20 吝啬的国度

    吝啬的国度 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 在一个吝啬的国度里有N个城市,这N个城市间只有N-1条路把这个N个城市连接起来.现在,Tom在第S号城市,他有 ...

  7. 题目20: 吝啬的国度

    吝啬的国度 时间限制: 1000 ms  |  内存限制: 65535 KB 难度: 3 描述 在一个吝啬的国度里有N个城市,这N个城市间只有N-1条路把这个N个城市连接起来.现在,Tom在第S号城市 ...

  8. NOJ 20 吝啬的国度

    开始做深搜的题,这是一种比较常见的递归,就是直接看去的点是从那来的,标记一下避免重复搜. 深搜的注意个人认为,1,要在一定范围内一般是在递归在1e4的范围内: 2,就是要注意标记,不然也可能导致超时的 ...

  9. 小白算法练习 NYOJ 吝啬的国度 dfs+邻接表

    吝啬的国度 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 在一个吝啬的国度里有N个城市,这N个城市间只有N-1条路把这个N个城市连接起来.现在,Tom在第S号城市,他有 ...

最新文章

  1. 35岁老码农:老板,你看我还有机会吗?
  2. 学计算机高考英语听力考试时间,北京高考英语听力考试时间
  3. kali 安装java jdk
  4. 解决逆向工程mapper映射文件不发布问题
  5. Guava的Collections2:过滤和转换Java集合
  6. blog.mm index.php,每天一个WordPress文件:index.php
  7. 《Learning OpenCV3》ch18:相机模型与标定
  8. Hadoop,Hbase伪集群安装步骤
  9. Android NIO(Noblocking I/O非阻塞I/O)小结
  10. OSPFv3中LSA详解(七)——Type4类LSA详解
  11. mysql insert优化_如何优化MySQL insert性能
  12. layabox 文本 html,LayaBox:富文本HtmlDivElement常用设置
  13. java 组织机构代码_JAVA实现社会统一信用代码校验的方法|chu
  14. uni-app H5实现扫码登录功能
  15. 【Pytorch深度学习实战】(4)前馈神经网络(FNN)
  16. js滚动数字动画效果
  17. 方程求根的迭代法——牛顿迭代法
  18. 我的世界服务器神秘修改节点,我的世界NBT指令修改神秘时代4MOD方法详解
  19. mPEG-SG 甲氧基PEG琥珀酰亚胺戊二酸酯
  20. 火爆外网的ChatGPT,改Bug,敲代码不在话下

热门文章

  1. 极客兔兔 TensorFlow入门教程
  2. mac上优秀的键盘改键神器:Karabiner Elements完美支持m1芯片详细教程解析
  3. Android第三方支付--微信支付
  4. 体育赛事直播系统的实践之路
  5. (转帖)Redis的LRU和LFU区别
  6. 快速找出两个Word文档之间的差别
  7. 评测 R7 7735HS和i5 12500h选哪个 锐龙R77735HS和i512500h差距
  8. Elastic:运用 Elastic Maps 实时跟踪,可视化资产分布及地理围栏告警(二)
  9. 用户画像无头绪?手把手教你RFM模型
  10. Node安装教程及环境配置