求无向图中所有的环 C++ python

  • 顶点从1~n
  • 关键在于避免重复,可以给环定标准:第一个点是序号最小的(确定起点),第二个点是与第一个点相连两点中的较小的点(确定搜索方向)
  • 搜索每个长度和每个点做起点,是否成环
#include 
#include 
#include 

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]) {
        	// 环的终点要大于第二点(标准2) && 当前点不在路径里 && 当前点和起点相连
            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]) {
            // 标准1 && 当前点不在路径里
            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;
    // 至少要以n-length+1为起点
    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;
    // 最小长度是3
    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;
}

/*
测试1:
16
10 2
2 6
2 3
2 5
5 7
3 4
4 8
8 15
15 16
16 1
4 9
12 11
12 13
14 12
7 9
9 1
-1

测试2:
7
1 7
1 2
1 3
2 3
7 3
6 7
4 3
4 5
5 6
6 4
-1
*/
  • 参考,这里有python版本

你可能感兴趣的:(碎碎念,算法,c++)