- 顶点从1~n
- 关键在于避免重复,可以给环定标准:第一个点是序号最小的(确定起点),第二个点是与第一个点相连两点中的较小的点(确定搜索方向)
- 搜索每个长度和每个点做起点,是否成环
#include <iostream>
#include <vector>
#include <set>
using namespace std;
class Graph
{
public:
vector<set<int>> ps;
Graph(int n, vector<vector<int>> es)
{
ps.resize(n+1);
for (auto i : es)
{
ps[i[0]].insert(i[1]);
ps[i[1]].insert(i[0]);
}
}
};
struct cir {
vector<int> path;
vector<int> has;
cir(int i, int n) {
path.emplace_back(i);
has.resize(n+1);
has[i] = 1;
}
};
int find_cirs_start_with(Graph g, int length, cir c) {
int cnt = 0, l = c.path.size(), last = c.path[l-1];
if(l == length-1) {
for(int p : g.ps[last]) {
if(p > c.path[1] && !c.has[p] && g.ps[p].find(c.path[0])!=g.ps[p].end()) {
++cnt;
for(int i : c.path) {
cout << i << " ";
}
cout << p << endl;
}
}
} else {
for(int p : g.ps[last]) {
if(p > c.path[0] && !c.has[p]) {
c.path.emplace_back(p);
c.has[p] = 1;
cnt += find_cirs_start_with(g, length, c);
c.path.pop_back();
c.has[p] = 0;
}
}
}
return cnt;
}
int find_cirs_of_length(Graph g, int length, int n) {
int cnt = 0;
for(int i = 1; i <= n-length+1; ++i) {
cir c(i, n);
cnt += find_cirs_start_with(g, length, c);
}
return cnt;
}
int find_all_cirs(Graph g, int n) {
int cnt = 0;
for(int i = n; i > 2; --i) {
cnt += find_cirs_of_length(g, i, n);
}
return cnt;
}
int main(int argc, char **argv)
{
vector<vector<int>> es;
int a, b, n;
cin >> n;
while (cin >> a)
{
if (a < 0)
break;
cin >> b;
if (b < 0)
break;
vector<int> tmp(2);
tmp[0] = a;
tmp[1] = b;
es.emplace_back(tmp);
}
cout << "********************************\n";
Graph g(n, es);
cout << find_all_cirs(g, n) << endl;
return 0;
}