吝啬的国度

来源:互联网 发布:adobe ps cc 2015 mac 编辑:程序博客网 时间:2024/04/29 01:39

吝啬的国度

时间限制: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)
样例输入
110 11 91 88 1010 38 61 210 49 53 7
样例输出
-1 1 10 10 9 8 3 1 1 8
来源
经典题目
上传者

张云聪



这个题目必须用邻接表。两种方法:一是用链表建图,广搜一遍,深搜会超时。二是用vector建立邻接表,可以深搜。

因为n个城市,只有n - 1条路,所以从始点走到任何一个点都只有一条路,所以搜索一遍,能够到达一个点的上一个结点是唯一确定的,用parent数组保存到一个结点必须经过的上一个结点。

从代码中图的数据结构也可以看出,一个封装之后的头结点可以代表一棵树,那么头结点的数组就可以保存邻接表形式的图。

方法一:邻接表建图,广搜


 #include<stdio.h>#include<stdlib.h>#include<string.h>#include<iostream>#include<queue>using namespace std;typedef struct node{int v;struct node *next;}node;typedef struct Graph{node *vertex;}Graph;int n, parent[100001];Graph g[100001];void read();void bfs(int v);int main(){int M, s, i;scanf("%d", &M);while(M--){scanf("%d %d", &n, &s);for(i = 1; i <= n; i++)g[i].vertex = NULL;for(i = 0; i < n - 1; i++){read();}memset(parent, 0, sizeof(parent));bfs(s);parent[s] = -1;for(i = 1; i < n; i++)printf("%d ", parent[i]);printf("%d\n", parent[n]);}return 0;}void bfs(int v){queue <int> Q;int i, cur, visit[100001];node *e;Q.push(v);memset(visit, 0, sizeof(visit));visit[v] = 1;while(!Q.empty()){cur = Q.front();Q.pop();for(e = g[cur].vertex; e != NULL; e = e ->next){if(!visit[e ->v]){visit[e ->v] = 1;parent[e ->v] = cur;Q.push(e ->v);}}}}void read(){node *e;int j, k;scanf("%d %d", &j, &k);e = (node *)malloc(sizeof(node));e ->v = j;e ->next = NULL;e ->next = g[k].vertex;g[k].vertex = e;e = (node *)malloc(sizeof(node));e ->v = k;e ->next = NULL;e ->next = g[j].vertex;g[j].vertex = e;}                

方法二:vector建立邻接表,深搜:


 #include<stdio.h>#include<iostream>#include<string.h>#include<vector>using namespace std;vector <int> g[100001];//创建一个含有100001个元素的vectorint parent[100001], visit[100001];void dfs(int v);int main(){int M, s, n, i, j, k;scanf("%d", &M);while(M--){scanf("%d %d", &n, &s);for(i = 1; i <= n; i++)g[i].clear();//移除每个容器中的所有数据for(i = 1; i < n; i++){scanf("%d %d", &j, &k);g[j].push_back(k);//向容器尾部加入一个数据g[k].push_back(j);}memset(visit, 0, sizeof(visit));visit[s] = 1;dfs(s);parent[s] = -1;for(i = 1; i < n; i++)printf("%d ", parent[i]);printf("%d\n", parent[n]);}return 0;}void dfs(int v){int i, cur;for(i = 0; i < g[v].size(); i++){//g[v].size()返回容器中实际元素个数cur = g[v][i];if(!visit[cur]){visit[cur] = 1;parent[cur] = v;dfs(cur);}}}        


0 0