Simple Cycles Edges CodeForces - 962F(点双连通分量)

题意:

  求出简单环的所有边,简单环即为边在一个环内

解析:

  求出点双连通分量,如果一个连通分量的点数和边数相等,则为一个简单环

  点双连通分量  任意两个点都至少存在两条点不重复的路径  即任意两条边都至少存在于一个简单环中

  那么我们要求的那个简单环 是不是就是点双连通分量的特殊情况   即任意两条边只存在于一个简单环中‘

  所以求点双连通分量  判断点数是否等于边数

#include <bits/stdc++.h>
#define mem(a, b) memset(a, b, sizeof(a))
using namespace std;
const int maxn = 1e6+10, INF = 0x7fffffff;
int n, m;
map<int, int> w[maxn];
int pre[maxn], iscut[maxn], bccno[maxn], dfs_clock, bcc_cnt, num[maxn];
vector<int> G[maxn], bcc[maxn];
vector<int> f;
vector<int> g[maxn];
struct Edge{
    int u, v;
    Edge(int u, int v): u(u), v(v){}
};

stack<Edge> S;

int dfs(int u, int fa)
{
    int lowu = pre[u] = ++dfs_clock;
    int child = 0;
    for(int i=0; i<G[u].size(); i++)
    {
        int v = G[u][i];
        Edge e  = Edge(u, v);
        if(!pre[v])
        {
            S.push(e);
            child++;
            int lowv = dfs(v, u);
            lowu = min(lowu, lowv);
            if(lowv >= pre[u])
            {
                iscut[u] = true;
                bcc_cnt++; bcc[bcc_cnt].clear();
                for(;;)
                {
                    Edge x = S.top(); S.pop();
                    if(bccno[x.u] != bcc_cnt) { bcc[bcc_cnt].push_back(x.u); bccno[x.u] = bcc_cnt; }
                    if(bccno[x.v] != bcc_cnt) { bcc[bcc_cnt].push_back(x.v); bccno[x.v] = bcc_cnt; }
                    g[bcc_cnt].push_back(w[x.u][x.v]);
                    if(x.u == u && x.v == v) break;
                }
            }
        }
        else if(pre[v] < pre[u] && v != fa)
        {
            S.push(e);
            lowu = min(lowu, pre[v]);
        }
    }
    if(fa < 0 && child == 1) iscut[u] = 0;
    return lowu;
}

void find_bcc()
{
    mem(pre, 0);
    mem(iscut, 0);
    mem(bccno, 0);
    dfs_clock = bcc_cnt = 0;
    for(int i=1; i<=n; i++)
        if(!pre[i]) dfs(i, -1);
}
int main()
{
    int u, v;
    cin >> n >> m;
    for(int i=1; i<=m; i++)
    {
        cin >> u >> v;
        w[u][v] = w[v][u] = i;
        G[u].push_back(v);
        G[v].push_back(u);
    }
    find_bcc();
    for(int i=1; i<=bcc_cnt; i++)
    {
        if(g[i].size() == bcc[i].size())
            for(int j=0; j<g[i].size(); j++)
                f.push_back(g[i][j]);
    }
    sort(f.begin(), f.end());
    cout<< f.size() <<endl;
    for(int i=0; i<f.size(); i++)
        cout<< f[i] << " ";
    cout<< endl;

    return 0;
}

猜你喜欢

转载自www.cnblogs.com/WTSRUVF/p/9671946.html
今日推荐