边双85pts

P8436 【模板】边双连通分量

する @ 2022-10-27 08:32:50

#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
int dfn[N],low[N],n,m,root,cnt,cnnt;
map<int,bool> mp[N];
vector<int> nbr[N],v[N];
bool vis[N];
void tarjan(int x,int fa)
{
    low[x]=dfn[x]=++cnt;
    for(int i=0;i<nbr[x].size();i++)
    {
        int y=nbr[x][i];
        if (y == fa) continue;
        if(dfn[y]==0)
        {
            tarjan(y,x);
            low[x]=min(low[x],low[y]);
            if(low[y]>dfn[x])
                mp[x][y]=1,mp[y][x]=1;
        }
        else if(y!=fa)
            low[x]=min(low[x],dfn[y]);
    }
}
void dfs(int x)
{
    v[cnnt].push_back(x);
    vis[x]=1;
    for(int i=0;i<nbr[x].size();i++)
    {
        int y=nbr[x][i];
        if(vis[y]==0&&mp[x][y]==0)
            dfs(y);
    }
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        int u,v;
        cin>>u>>v;
        nbr[u].push_back(v);
        nbr[v].push_back(u);
    }
    for(root=1;root<=n;root++)
        if(dfn[root]==0)
            tarjan(root,0);
    for(int i=1;i<=n;i++)
        if(vis[i]==0)
        {
            cnnt++;
            dfs(i);
        }
    cout<<cnnt<<endl;
    for(int i=1;i<=cnnt;i++)
    {
        cout<<v[i].size()<<" ";
        for(int k=0;k<v[i].size();k++)
            cout<<v[i][k]<<" ";
        puts("");
    }
    return 0;
}

by Halo_world @ 2022-10-27 08:58:34

我觉得,你考虑

map的常数

这道题不需要map为什么还要开呢


by 晴空一鹤 @ 2022-10-27 09:01:51

@する 你这把两个节点构成的环直接给拆掉了

例:2 2

1 2

2 1


by 晴空一鹤 @ 2022-10-27 09:05:29

你的判断过程应该改为如果一个节点连同他的子树都到达不了dfn更小的点,那这一点到他父节点的边就是桥


by する @ 2022-10-27 09:06:29

谢谢你


|