有没有一种用vector存图写边双联通做法。

P8436 【模板】边双连通分量

Hellsing_Alucard @ 2023-05-01 21:33:32

#include <bits/stdc++.h>

using namespace std;

#define pii pair<int,int>

inline int read(){
    int x=0,f=1;char ch=getchar();
    while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
    return x*f;
}
vector<pii>g[550500];
int n,m;
int dfn[500500],low[500500],t;
bool bri[500500];
int c[500500],cnt,colornum;
stack<int>s;
vector<int>ans[500500];
inline void tarjan(int u, int fa) {
    dfn[u] = low[u] = ++t;
    s.push(u);
    for(auto i:g[u]) {
        int v = i.first, it = i.second;
        if (v == fa) continue;
        if (!dfn[v]) {
            tarjan(v, u);
            low[u] = min(low[u], low[v]);
            if (dfn[u] < low[v]) bri[it] = bri[it^ 1] =1;
        }
        else if(dfn[v]<dfn[u])low[u] = min(low[u], dfn[v]);
    }
    if(dfn[u] == low[u]) {
        int v;
        colornum ++;
        do {
            v =s.top();s.pop();
            c[v] = colornum;
            ans[colornum].push_back(v);
        } while(u != v);
    }
    return;
    return;
}

int main() {
    n=read();m=read();
    for (int i = 1,u,v; i <= m; i++){
        u=read();v=read();
        g[u].emplace_back(v,2*i);
        g[v].emplace_back(u,2*i+1);
    }
    for (int i = 1; i <= n; i++) if (!dfn[i]) tarjan(i, 0);
    cout<<colornum<<endl;
    for(int i = 1; i <= colornum; i ++) {
        cout <<ans[i].size()<<" ";
        for(auto v:ans[i]) {
            cout <<v <<" ";
        }
        cout <<endl;
    }
    return 0;
}

这是根据自己理解写出来的代码,但是会 wa


by Pengzt @ 2023-05-01 22:06:02

@rubish 需要额外判断一下重边?


|