吝啬的国度
时间限制: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
/*这道题用链表也可以做,不过代码量大很多,感觉这道题就是考vector用法,比赛时用其他方法做得不偿失*/
#include<string.h>
#include<vector>
#include<algorithm>
# include <stdio.h>
using namespace std;
int pre[100005]; // pre数组存储该元素是否已经找到父节点的状态
vector<int> v[100005]; // vector 容器对父节点的添加尤为方便
void dfs(int cur) // 传入 cur 找出所有以cur为父节点的元素
{
for( int i=0;i< v[cur].size() ;i++) // v[cur].size() 是当前节点的子节点的数量
{
if( pre[ v[cur][i] ] ) //pre数组存储该元素是否已经找到父节点的状态
continue; // 若存在父节点则继续遍历,特别注意的是 起点的父节点是-1,
//可以理解为,一个不存在的父节点
pre[ v[cur][i] ]=cur; // 标记相连节点的父节点为cur
dfs ( v[cur][i] ); // 进行深搜,把父节点的父节点找出来
}
}
int main()
{
int ncase;
scanf("%d",&ncase);
while(ncase--)
{
memset(v,0,sizeof(v));
memset(pre,0,sizeof(pre) ); //pre数组存储该元素是否已经找到父节点的状态
//默认全无父节点
int n,s;
scanf("%d%d",&n,&s); // s表示出发城市
pre[s]=-1; // 可以理解为,一个不存在的父节点-1
for(int i=0;i<n-1;i++)
{
int temp1,temp2;
scanf("%d%d",&temp1,&temp2);
v[temp1].push_back(temp2); //城市a与b相连, 要记住vector的操作格式
v[temp2].push_back(temp1); //城市b与a肯定也相连
}
dfs(s);//必须从起点开始搜索,因为刚才我们已经给起点赋了父节点-1
// 你可以试试dfs(2);看看
for(int i=1;i<n;i++)
printf("%d ",pre[i]);
printf("%d\n",pre[n]);
}
return 0;
}
/* 刚接触C语言的时候,感觉算法套路太深,是给聪明人准备的,偷懒不想学,后来阴差阳错学了点算法,用算法解题可谓是高潮连连,真是倍儿爽,每每做题都想用学过的算法,对vector这种知识点不够重视。要拓宽知识面,多学点,选择的余地更大些。*/
本文介绍了如何使用C++中的vector容器解决一道算法问题——吝啬的国度。在这个问题中,我们需要找出从特定城市出发到达其他城市的必经之路。文章通过样例输入和输出展示了算法的应用,并强调了掌握多种编程工具如vector的重要性。
486

被折叠的 条评论
为什么被折叠?



