NYOJ 20 吝啬的国度
2012-07-05 16:47
225 查看
吝啬的国度
时间限制: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 18 1010 33 710 41 91 88 61 29 5则首先得到一个不包含出发城市的子图:
![](http://my.csdn.net/uploads/201207/05/1341480011_2333.jpg)
在输入数据1 8时之后,上面的子图与出发城市相连,图中红色方块代表出发城市,虚线箭头代表并未在邻接表中建立此联系:
![](http://my.csdn.net/uploads/201207/05/1341480002_6004.jpg)
#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; } } }
相关文章推荐
- ACM--BFS--图--nyoj 20--吝啬的国度
- NYOJ 20 吝啬的国度
- nyoj20 吝啬的国度
- nyoj 20 吝啬的国度(邻接表+bfs)
- NYOJ20 吝啬的国度 【深搜】
- NYOJ 20--吝啬的国度 【DFS】
- NYOJ 20 吝啬的国度 广度优先搜索
- NYOJ-20-吝啬的国度(树的先序遍历)
- nyoj 20 吝啬的国度
- NYOJ-20 吝啬的国度
- 【DFS,双向】NYOJ-20-吝啬的国度
- nyoj20吝啬的国度——DFS
- NYOJ20吝啬的国度广度搜索
- NYOJ 20 吝啬的国度
- nyoj20吝啬的国度_广搜
- NYOJ20吝啬的国度
- NYOJ 20 吝啬的国度
- NYOJ 20 吝啬的国度(深搜)
- nyoj 20 吝啬的国度
- NYOJ 20 吝啬的国度