一个疑问

P8436 【模板】边双连通分量

Super_modfish @ 2023-10-20 10:48:46

这样写是对的:

#include <bits/stdc++.h>
#define ll long long
#define rll register ll
#define cll const ll
#define N 5000005
using namespace std;
inline ll read()
{
    rll x=0;bool f=1;register char c=getchar();
    while(c<48||c>57){if(c=='-') f=0;c=getchar();}
    while(c>=48&&c<=57){x=x*10+(c^48);c=getchar();}
    return f?x:-x;
}
inline void write(ll x)
{
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+48);
}
cll n=read();
ll m=read(),ts,idx,cnt,f[N],w[N],v[N],h[N],ne[N],dfn[N],low[N];
bitset<N> vis,flag;
vector<ll> dcc[N];
inline void add(ll x,ll y){v[idx]=y,ne[idx]=h[x],h[x]=idx++;}
inline void dfs(ll x,ll F)
{
    dfn[x]=low[x]=++ts;
    for(rll i=h[x];~i;i=ne[i])
    {
        cll y=v[i];
        if(!dfn[y])
        {
            dfs(y,i),low[x]=min(low[x],low[y]);
            if(low[y]>dfn[x])
                flag[i]=flag[i^1]=1;
        }
        else if(i!=(F^1))
            low[x]=min(low[x],dfn[y]);
    }
}
inline void dfs2(ll x)
{
    vis[x]=1,dcc[cnt].push_back(x);
    for(rll i=h[x];~i;i=ne[i])
    {
        cll y=v[i];
        if(!vis[y]&&!flag[i]) dfs2(y);
    }
}
int main()
{
    memset(h,-1,sizeof h);
    while(m--)
    {
        cll x=read(),y=read();
        add(x,y),add(y,x);
    }
    for(rll i=1;i<=n;i++)
        if(!dfn[i]) dfs(i,0);
    for(rll i=1;i<=n;i++)
        if(!vis[i]) cnt++,dfs2(i);
    write(cnt),putchar('\n');
    for(rll i=1;i<=cnt;i++)
    {
        write(dcc[i].size()),putchar(' ');
        for(rll j=0;j<dcc[i].size();j++)
            write(dcc[i][j]),putchar(' ');
        putchar('\n');
    }
    return 0;
}

这样写是错的:

#include <bits/stdc++.h>
#define ll long long
#define rll register ll
#define cll const ll
#define N 5000005
using namespace std;
inline ll read()
{
    rll x=0;bool f=1;register char c=getchar();
    while(c<48||c>57){if(c=='-') f=0;c=getchar();}
    while(c>=48&&c<=57){x=x*10+(c^48);c=getchar();}
    return f?x:-x;
}
inline void write(ll x)
{
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+48);
}
cll n=read();
ll m=read(),ts,idx,cnt,f[N],w[N],v[N],h[N],ne[N],dfn[N],low[N];
bitset<N> vis,flag;
vector<ll> dcc[N];
inline void add(ll x,ll y){v[idx]=y,ne[idx]=h[x],h[x]=idx++;}
inline void dfs(ll x,ll F)
{
    dfn[x]=low[x]=++ts;
    for(rll i=h[x];~i;i=ne[i])
    {
        cll y=v[i];
        if(!dfn[y])
        {
            dfs(y,x),low[x]=min(low[x],low[y]);
            if(low[y]>dfn[x]) flag[y]=1;
        }
        else if(y!=F)
            low[x]=min(low[x],dfn[y]);
    }
}
inline void dfs2(ll x)
{
    vis[x]=1,dcc[cnt].push_back(x);
    for(rll i=h[x];~i;i=ne[i])
    {
        cll y=v[i];
        if(!vis[y]&&!flag[y]) dfs2(y);
    }
}
int main()
{
    memset(h,-1,sizeof h);
    while(m--)
    {
        cll x=read(),y=read();
        add(x,y),add(y,x);
    }
    for(rll i=1;i<=n;i++)
        if(!dfn[i]) dfs(i,0);
    for(rll i=1;i<=n;i++)
        if(!vis[i]) cnt++,dfs2(i);
    write(cnt),putchar('\n');
    for(rll i=1;i<=cnt;i++)
    {
        write(dcc[i].size()),putchar(' ');
        for(rll j=0;j<dcc[i].size();j++)
            write(dcc[i][j]),putchar(' ');
        putchar('\n');
    }
    return 0;
}

希望有好心人详细解释,帮助巨蒻理解。免得考场上打不出


by zdc_ @ 2023-10-20 11:16:42

如果有重边第二种就不行了


|