AtCoder Beginner Contest 168 D - .. (Double Dots) --最短路树

题目:

在这里插入图片描述

题目链接:

点我就可以做题啦

题目大意:

给一个双向图,以 1 号节点为根节点,在其他节点上竖立一个牌子,代表可以到达几号点,问最后是否
存在这样一棵树:满足所有点都可以到达 1 号点 -- 并且每个点到 1 号点的距离都是最短的。	

侃侃:

先来看一下第二个样例:
	6 9
	3 4
	6 1
	2 4
	5 3
	4 6
	1 5
	6 2
	4 5
	5 6

在这里插入图片描述
我们发现如果要在每个节点的位置竖立一个牌子,那么一定是竖立它的父节点(因为我们最 后要想到达 根节点,必然是向上走的),所以我们只需要知道每个节点的父节点就可以啦,如果说某个节点没有父节点,那么这个图必然是不满足条件的(说明无法到达根节点)

做法:

因为要求每个节点的父节点是 who,所以需要用 BFS 进行层次遍历一下,通过上图我们看到 图中是
存在环的,用 DFS 的话并不能达到层次的效果(层次也就是我们所说的深度),接着最后遍历一下就可
以啦。

Code:

#include <set>
#include <map>
#include <queue>
#include <deque>
#include <stack>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>

#define x first
#define y second

using namespace std;

typedef long long LL;
typedef pair<int,int>PII;

const int maxn = 2e5 + 10;

int deep[maxn],fa[maxn];

int t,n,m;

vector<int>G[maxn];

void BFS(int root) {
	queue<int>Q;
	Q.push(root);
	fa[root] = 1;
	while(Q.size()) {
		int top = Q.front();
		Q.pop();
		for(int i = 0; i < G[top].size(); i ++) {
			int y = G[top][i];
			// 一个节点只能有一个父亲 
			if(fa[y]) continue;
			Q.push(y);
			fa[y] = top;
		}
	}
	return ;
}

int main(void) {
	scanf("%d%d",&n,&m);
	int u,v;
	for(int i = 1; i <= m; i ++) {
		scanf("%d%d",&u,&v);
		G[u].push_back(v);
		G[v].push_back(u);
	}

	BFS(1);
	bool flag = true;
	for(int i = 2; i <= n; i ++) {
		// 如果说某个节点没有父亲,则不在树上,必然走不到 1  
		// 有可能是孤立的点
		if(fa[i] == 0) {
			flag = false;
			break;
		}
	}
	if(!flag) puts("No");
	else {
		puts("Yes");
		for(int i = 2; i <= n; i ++) {
			printf("%d\n",fa[i]);
		} 
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43619271/article/details/106186592
今日推荐