思路:
连通图深搜一次,不要将人在这里的城市 去其他目标城市 一次次深搜,直接一次深搜。扩展下去。遇到一个没有访问过的节点就保存他的父节点。这就是必经之路。
吝啬的国度
时间限制:
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
-
第一行输入一个整数M表示测试数据共有M(1<=M<=5)组
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100001
typedef int VexType;
struct Vnode{
VexType data;
struct Vnode *next;
};
/* Vnode是顶点的结点结构 */
typedef Vnode Lgraph[MAX]; /* Lgraph是一维数组类型标识符 */
/* 函数原形声明 */void creat_L(Lgraph G);
void out_L(Lgraph G);
void dfsL(Lgraph G,int v);
int n,e;
int *a; //用来存取每个城市必须经过的前一个。
Vnode *Ga;
bool *vis; /* Ga是邻接链表的表头数组名 */
/* 主函数 */
int main(){
int v1,i,flag,c,j;
/* 顶点访问的标志数组 */
scanf("%d",&c); /* 建立图邻接链表Ga */
while(c--)
{
scanf("%d %d",&n,&e);
Ga=(Vnode*)malloc(sizeof(Vnode)*(n+1));
vis=(bool*)malloc(sizeof(bool)*(n+1));
a=(int*)malloc(sizeof(int)*(n+1));
creat_L(Ga);
for(int j=0;j<=n;j++)
vis[j]=0;
dfsL(Ga,e);
a[e]=-1;
for(int i=1;i<=n;i++){
printf("%d ",a[i]);}
printf("\n");
}
/* 输出邻接链表Ga */
}/* main */
/* 建立邻接链表 */
void creat_L(Lgraph G){
Vnode *p,*q;
int i,j,k;
for(i=1; i<n; i++) {
G[i].data=i; G[i].next=NULL;
}
for(k=1;k<=n-1; k++){
scanf("%d%d",&i,&j);
/* p结点链接到第j条链 */
q=(Vnode *)malloc(sizeof(Vnode));
q->data=i;
q->next=G[j].next;G[j].next=q;
q=(Vnode *)malloc(sizeof(Vnode));
q->data=j;
q->next=G[i].next; G[i].next=q; /* q结点链接到第i条链 */
}
}
/* creat_L */
/* 邻接链表的简单输出,为了检查输入是否正确 */
void out_L(Lgraph G){
int i;
Vnode *p;
for (i=1; i<=n; i++) {
p=G[i].next;
while(p!=NULL){
printf("%5d",p->data); p=p->next;
}
printf("\n");
}
} /* out_L */
/* 深度优先遍历图 */
void dfsL(Lgraph G,int v){
Vnode *p;
vis[v]=1; /* 顶点v被访问,标志置1 */
p=G[v].next;
int c=v;//搜到了城市v用c保存
while(p)
{
v=p->data;
if(vis[v]==0)a[v]=c;//保存c 因为下面的v与c相连。
if(vis[v]==0)dfsL(G,v);
p=p->next;
}
/* 顶点v未被访问时继续遍历 */
}
吝啬的国度
时间限制:
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
-
第一行输入一个整数M表示测试数据共有M(1<=M<=5)组