AT_abc213_d [ABC213D] Takahashi Tour 题解

题目传送门

题目大意

给定一个 n n n 个点的无向图,从根节点 1 1 1 开始,按照以下遍历规则遍历:

  1. 如果这个点所能到达的点中有没有遍历过的,那么就按照编号的从小到大的顺序遍历。

  2. 否则,那么:

    • 如果此点为 1 1 1,结束遍历。
    • 否则回溯到上一点。

请你按照遍历顺序输出到达过的点的编号。

解题思路

我们肯定得存储这个无向图对吧,于是就用到了 vector 容器。题目要求按照编号的递增顺序进行遍历对吧,所以就把每个节点的子节点都给 sort 排下序。题目说如果这个点的子节点中有没被遍历过的就遍历,都遍历过了就回溯对吧,所以我们直接 dfs 爆搜,输出一下当前节点的编号,遍历子节点,打标记,然后我们就会惊奇地发现这题居然如此简单。

如果不会建图的话,我就讲一下(会的神犇可以跳过)。

首先 vector 可以理解为一个动态数组,而 vector<int> a[200010] 就是定义一个二维数组,a[1].push_back(2) 就是将 2 2 2 添加在了编号为 1 1 1 的序列中,因此我们使用 vector 建图的时候,a[1].push_back(2) 就可以理解为 1 1 1 2 2 2 之间创建了一条边 1 → 2 1\to2 12,而 a[1].push_back(2),a[2].push_back(1) 就可以理解为创建了两条边 1 → 2 , 2 → 1 1\to2,2\to1 12,21,这就是无向图的创建。

CODE:

#include <bits/stdc++.h>
using namespace std;
vector<int> a[200010];
bool vis[200010];
void dfs(int now) {
    
    
	cout << now << ' ';
	vis[now] = true;
	for (int i = 0; i < a[now].size(); i++) 
    	if (!vis[a[now][i]])
        	dfs(a[now][i]), cout << now << ' ';
}
int main()
{
    
    
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	int n;
	cin >> n;
	for (int i = 1; i < n; i++)	{
    
    
		int u, v;
		cin >> u >> v;
	    a[u].push_back(v);
		a[v].push_back(u);
	}
	for (int i = 1; i <= n; i++)
		sort(a[i].begin(), a[i].end());
	dfs(1);
	return 0;
}

总结

这道题目没有什么难点,只要我们跟着题目的思路走,就可以轻松写完代码。

猜你喜欢

转载自blog.csdn.net/2301_76224755/article/details/139443381