AtCoder Beginner Contest 168 D - .. (Double Dots)(建无向图+BFS)

Problem Statement

There is a cave.

The cave has N rooms and M passages. The rooms are numbered 1 to N
, and the passages are numbered 1 to M. Passage i
connects Room Ai and Room Bi bidirectionally. One can travel between any two rooms by traversing passages. Room 1 is a special room with an entrance from the outside.

It is dark in the cave, so we have decided to place a signpost in each room except Room 1. The signpost in each room will point to one of the rooms directly connected to that room with a passage.

Since it is dangerous in the cave, our objective is to satisfy the condition below for each room except Room
1.

If you start in that room and repeatedly move to the room indicated by the signpost in the room you are in, you will reach Room 1 after traversing the minimum number of passages possible.
Determine whether there is a way to place signposts satisfying our objective, and print one such way if it exists.

Input

Input is given from Standard Input in the following format:

Output

If there is no way to place signposts satisfying the objective, print No.

Otherwise, print N lines. The first line should contain Yes, and the i-th line (2≤i≤N)
should contain the integer representing the room indicated by the signpost in Room i.

Sample Input

4 4
1 2
2 3
3 4
4 2

Sample Output

Yes
1
2
2

题意:有n个点,给m个两点之间得关系,问是否每个点都能到1,是输出“Yes”,并且输出每个点到1得最短路上得前一个点,否则输出“No”。

#include<bits/stdc++.h>
#include <cstdlib>
#include <ctime>
using namespace std;
#define pi acos(-1)
#define mod 1000000007
#define ll long long
#define ull unsigned long long
#define mem(a) memset(a,0,sizeof(a))
#define cio ios::sync_with_stdio(false);
int s[200010];    // 结果
vector<int>v[200010]; // 建图
int main()
{   	
	int n, m;
	cin >> n >> m;
	int a, b;
	for(int i = 1; i <= m; i++){
		cin >> a >> b;
		v[a].push_back(b);  // 无向图两点都需要push
		v[b].push_back(a);
	}
	queue<int>q; // 队列用于搜索路径
	s[1] = 0; // 从1开始
	for(int i = 0; i < v[1].size(); i++){ // 将和1直接相连得点进去队列
		q.push(v[1][i]);
		s[v[1][i]] = 1; // 前一个点为1
	}
	while(!q.empty()){
		int p = q.front(); // 取队首元素
		q.pop(); // 移除队列
		for(int i = 0; i < v[p].size(); i++){ // 将与队首元素直接相连的点进入队列
			if(s[v[p][i]]==0&&v[p][i]!=1){ // 如果该点未走过,进入队列
				q.push(v[p][i]);
				s[v[p][i]] = p; // 该点前一个点即为队首元素p
			}
		}
	}
	int flag = 1;
	for(int i = 2; i <= n; i++){ // 判断是否每个点都可到达1
		if(s[i]==0){
			flag = 0;
			break;
		}
	}
	// 输出结果
	if(!flag){
		cout << "No" << endl;
	}else{
		cout << "Yes" << endl;
		for(int i = 2; i <= n; i++){
			cout << s[i] << endl;
		}
	}
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值