hpu 1713 参观城市 <bfs+邻接表>

来源:互联网 发布:淘宝店自动充值软件 编辑:程序博客网 时间:2024/06/17 23:42

1713: 参观城市

时间限制: 1 Sec  内存限制: 128 MB
提交: 35  解决: 20
[提交][状态][讨论版]

题目描述

有N个城市,这N个城市间只有N-1条路把这个N个城市连接起来。现在,小明在第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 101 21 91 83 78 68 109 510 310 4

样例输出

8 1 10 10 9 8 3 10 1 -1

提示

来源

思路:

             从起点开始进行广搜,然后找起点周围的点将它们的左顶点进行记录,然后找它周围的点的周围的点进行记录它们的左顶点,直至所有的点都搜完为止,将从第一个点开始将它们的做顶点输出就OK了!(第一次用神搜+邻接表,感觉真的太好了!)

 

代码:

#include <stdio.h>#include <string.h>#include <queue>#include <algorithm>using namespace std;int n,s;int pre[100005];int vis[100005];int edgenum;int head[100005];struct Edge//建立邻接表 {int from,to,val,next;}edge[100005];void init(){memset(head,-1,sizeof(head));memset(vis,0,sizeof(vis));edgenum=0;memset(pre,-1,sizeof(pre));//保存一个数左边连接的数字 }void addedge(int u,int v,int w)//建立边! {Edge E={u,v,w,head[u]};edge[edgenum]=E;head[u]=edgenum++;}void bfs(int x)//进行广搜搜s周围的点,并将它们的左节点保存一下! {queue<int>q;//队列里面装的都是需要搜的周围的点的点! memset(vis,0,sizeof(vis));//用来标记是否找过这些点的周围的点 vis[x]=1;q.push(x);while(!q.empty()){int u=q.front();//出队列后进行查找它周围的点 q.pop();for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].to;if(vis[v]==0)//如果没有查找过就将其标记,进队列,赋值! {pre[v]=u;vis[v]=1;q.push(v);//进队列后继续查找! }}}}int main(){int T;scanf("%d",&T);while(T--){init();scanf("%d%d",&n,&s);//n为城市的个数 ,s为起点城市! int a,b;for(int i=1;i<n;i++){scanf("%d%d",&a,&b);addedge(a,b,1);//增加无向边 addedge(b,a,1);}bfs(s);//进行广搜,以s为起点与1-n号点相连的边的左顶点!并进行标记! for(int i=1;i<n;i++)//输出与各点相连的边的左顶点! {printf("%d ",pre[i]);}printf("%d\n",pre[n]);}return 0;}


 

 

0 0
原创粉丝点击