用一个集合保存已经经过的点,path数组保存走过的路径,从一个点开始dfs,如果再次来到走过点就说明发现了环,此时去path中找到第一次出现这个点的位置,从这个点往后就是环中的元素了。
#include<iostream>
#include<vector>
#include<algorithm>
#include<map>
#include<math.h>
#include<set>
#include<string>
#include<stack>
using namespace std;
#include<queue>
#include<sstream>
//s集合用来存放环中的元素,也就是放答案的集合
set<int>s;
//map1是图结构,当前点-可达到的点。used保存经过的点,path保存经过的点的路径,cur当前节点,pre上一个节点
void dfs(map<int, set<int> >& map1, set<int>& used, vector<int>& path,int cur,int pre)
{
//cout << cur<<" "<<pre << endl;
if (s.size() != 0)
{
return;
}
//再次来到一个经过了的点
if (used.count(cur) == 1)
{
int begin = 0;
for (int i = 0; i < path.size(); i++)
{
if (path[i] == cur)
{
begin = i;
break;
}
}
for (int i = begin; i < path.size(); i++)
{
s.insert(path[i]);
}
return;
}
set<int>::iterator it;
for (it = map1[cur].begin(); it != map1[cur].end(); it++)
{
//这里pre==(*it)是防止ABA这样的情况出现
if ((*it) == pre)
{
continue;
}
used.insert(cur);
path.push_back(cur);
dfs(map1, used, path, (*it),cur);
path.pop_back();
used.erase(cur);
}
}
int main()
{
map<int, set<int> >map1;
int n = 0;
cin >> n;
for (int i = 0; i < n; i++)
{
int a, b;
cin >> a >> b;
map1[a].insert(b);
map1[b].insert(a);
}
set<int>used;
vector<int>path;
dfs(map1, used, path, 1,-1);
set<int>::iterator it;
for (it = s.begin(); it != s.end(); it++)
{
cout << (*it) << " ";
}
return 0;
}