nyoj 20-吝啬的国度 (DFS)
20-吝啬的国度
内存限制:64MB
时间限制:1000ms
Special Judge: No
accepted:12
submit:43
题目描述:
在一个吝啬的国度里有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
拓展:
free对内存进行释放,主要是将malloc、new、realloc等申请的内存进行释放
STL中的vector是进行动态内存的追加,用free进行内存释放会使编译器不清楚从哪开始释放
分析:
①、在数据结构方面我们选择二维vector,用vector来存对应城市相邻的城市,用.size()就可以得到与该城市相邻的城市个数
②、因为DFS是线性的、回溯型搜索方式,将会直接或回溯式的找到前面直接相邻的城市
步骤、
①、通过vector建立两个城市的双向距离关系
②、使用dfs从入口点s进入,将每一个相邻城市的前驱都赋值为对应的s
核心代码:
1 void dfs(int s) 2 { 3 for(int i = 0; i < A[s].size(); ++ i) 4 { 5 if(f[A[s][i]]) continue; 6 f[A[s][i]] = s; 7 dfs(A[s][i]); 8 } 9 }
C/C++代码实现(AC):
1 #include <iostream> 2 #include <algorithm> 3 #include <cstring> 4 #include <cstdio> 5 #include <cmath> 6 #include <stack> 7 #include <map> 8 #include <queue> 9 10 using namespace std; 11 const int MAXN = 1e5 + 5; 12 int f[MAXN]; 13 vector <int> A[MAXN]; 14 15 void init(int n) 16 { 17 while(n --) 18 { 19 int a, b; 20 scanf("%d%d", &a, &b); 21 A[a].push_back(b); 22 A[b].push_back(a); 23 } 24 } 25 26 void dfs(int s) 27 { 28 for(int i = 0; i < A[s].size(); ++ i) 29 { 30 if(f[A[s][i]]) continue; 31 f[A[s][i]] = s; 32 dfs(A[s][i]); 33 } 34 } 35 36 int main() 37 { 38 int t; 39 scanf("%d", &t); 40 while(t --) 41 { 42 int n, s; 43 memset(f, 0, sizeof(f)); 44 memset(A, 0, sizeof(A)); 45 scanf("%d%d", &n, &s); 46 init(n - 1); 47 48 dfs(s); 49 f[s] = -1; 50 for(int i = 1; i < n; ++ i) 51 printf("%d ", f[i]); 52 printf("%d\n",f[n]); 53 } 54 return 0; 55 }