竹杖芒鞋轻胜马
谁怕?
一蓑烟雨任平生
这是PTA上一道作业题,大概就是在有向图中找出一个字典序最小的环,要求这个环连接了所有的点。
首先想到的就是DFS了,思路如下:
- 根据输入,建立所有的有向边,当然可能出现双向的
- 使用深度优先遍历,用一个vector记录路径,用一个vis数组记录当前路径经过的点
- 每进入下一个点前,判断这个点有没有访问过,是不是连通
- 如果记录路径的vector存下了n个点,说明已经存下了所有点了,然后看首尾相等吗
- 首尾相等则说明找到答案了,我们是按照从小到大找的,所以不用考虑字典序
看上去没大问题了,写下来,一交,超时了。
想了好多可能超时的点,都觉得不科学,按理说已经不能降低复杂度了。
只能搜一下了,看了下博客上别人的题解,才意识到问题没那么简单。
这个题目有几个信息必须抓住:
- 环上包括了所有的点
- 字典序最小,则意味着环要有个头的话,一定是1!
- 第三点最重要:如果剩下的点中没有能和1相连通的,就不用遍历了,因为没有能够连接头的了,成不了环
有了以上分析,就可以下写出下面的代码了:
#include <cstdio>
#include <iostream>
#include <vector>
using namespace std;
int g[21][21];
int n;
vector<int> ans;
bool vis[21];
void dfs(int root, vector<int> &tpath, bool &flag) {
if (flag) return ;