[蓝桥杯]:发现环 -- 并查集、DFS
题目:
样例:
考察点:
并查集判断是否有环,DFS寻找从环的起点到终点的路径。
图解:
Code:
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1e5 + 10;
int vis[maxn],fa[maxn];
vector<int>G[maxn],ve;
int n,pos = 0,l,r;
void init() {
for(int i = 1; i <= n; i ++) {
fa[i] = i;
}
return ;
}
int get(int x) {
return x == fa[x] ? x : fa[x] = get(fa[x]);
}
void Union(int x,int y) {
int xx = get(x);
int yy = get(y);
if(xx == yy) return ;
fa[yy] = xx;
return ;
}
// 标记是否已经找到合适的路径
bool flag = true;
void DFS(int l,int r) {
if(l == r) {
sort(ve.begin(),ve.end());
for(int i = 0; i < ve.size(); i ++) {
cout << ve[i];
// 注意行末空格
if(i != ve.size() - 1) cout << " ";
}
flag = false;
return ;
}
for(int i = 0; i < G[l].size(); i ++) {
int y = G[l][i];
if(vis[y] == 0 && flag) {
ve.push_back(y);
vis[y] = 1;
DFS(y,r);
// 还原现场(回溯),此路径有可能不是我们所要的最终路径
ve.pop_back();
vis[y] = 0;
}
}
return ;
}
int main(void) {
scanf("%d",&n);
int u,v;
init();
for(int i = 1; i <= n; i ++) {
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
// 并查集寻找环,找到路径的起点和终点
if(get(u) != get(v)) Union(u,v);
else {
l = u,r = v;
}
}
// 将起点入队并且标记
ve.push_back(l);
vis[l] = 1;
DFS(l,r);
return 0;
}
如果说年轻人未来是一场盛宴的话,那么我首先要有赴宴的资格。