原题链接:蓝桥杯2017年第八届真题-发现环
解题思路:
注意事项:
注意如果找到了解,不要回溯,因为回溯回去啥都回溯没了,所有找到解之后先打印完之和,直接退出程序,不需要回溯,还节约程序执行时间
参考代码:
#include <iostream> #include <vector> #include <set> using namespace std; const int N = 1e5 +10; int pre[N], vis[N]; vector<int> E[N]; set<int> path; void Init() { for(int i = 0; i < N; ++i) pre[i] = i; } int find(int x) { // 递归 (数据量大的时候使用迭代,因为递归会爆栈) return x == pre[x] ? x : pre[x] = find(pre[x]); } //int find(int x) { // 迭代 // int p = x, tmp; // while(x != pre[x]) x = pre[x]; // while(p != x) { // tmp = pre[p]; // pre[p] = x; // p = tmp; // } // return x; //} bool Union(int x, int y) { int x_root = find(x); int y_root = find(y); if(x_root != y_root) { pre[x_root] = y_root; return true; } return false; } void dfs(int s, int t) { if(s == t) { for (set<int>::iterator it = path.begin(); it != path.end(); ++it) { if (it != path.begin()) cout << ' '; cout << *it; } exit(0); // 找到了及时退出 } for(int i = 0; i < E[s].size(); ++i) { int u = E[s][i]; if(vis[u]) continue; vis[u] = 1; path.insert(u); dfs(u, t); vis[u] = 0; path.erase(u); } } int main() { int n, x, y, from, to; scanf("%d", &n); Init(); for(int i = 0; i < n; ++i) { scanf("%d%d", &x, &y); E[x].push_back(y); E[y].push_back(x); if(find(x) != find(y)) { Union(x, y); } else { from = x, to = y; } } path.insert(from); dfs(from, to); return 0; }
0.0分
0 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复