去重了,40昏,求调玄关

P2272 [ZJOI2007] 最大半连通子图

DGL__DGL_AFO @ 2024-09-15 21:57:47

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m;
int h[3145140],e[3145140],ne[3145140],idx;
int rr[3145140],c[3145140];
int st[3145140],s;
int dfn[3145140],low[3145140];
int stk[3145140],op;
int id[3145140];
int q[3145140],l,r;
int tcnt,scnt;
ll ans,gen,res,sid[3145140];
ll f[3145140],g[3145140],mod;
int qc[3145140],cq[3145140],dgl;

inline void add(int a,int b)
{
    idx++;
    ne[idx]=h[a];
    e[idx]=b;
    h[a]=idx;
}

inline void tarjan(int x)
{
    dfn[x]=++tcnt;
    low[x]=tcnt;
    stk[++op]=x;
    st[x]=1;

    for(int i=h[x];i;i=ne[i])
    {
        int y=e[i];
        if(!dfn[y])
        {
            tarjan(y);
            low[x]=min(low[x],low[y]);
        }
        else if(st[y])
          low[x]=min(low[x],dfn[y]);
    }

    if(dfn[x]==low[x])
    {
        int y;
        ++scnt;
        do{
            y=stk[op--];
            st[y]=0;
            id[y]=scnt;
            sid[scnt]++;
        } while(y!=x);
    }
}

inline void find()
{
    for(int i=1;i<=n;i++)
    {
        for(int j=h[i];j;j=ne[j])
      {
        int y=e[j]; 

        if(id[i]!=id[y])
        {
            rr[id[y]]++;
            c[id[i]]++;

            if(qc[id[y]]==1)
              continue;
            qc[id[y]]=1;
                cq[++dgl]=id[y];

            add(id[i]+n,id[y]+n);
            }

        }

        for(int j=1;j<=dgl;j++)
          qc[cq[j]]=0;
        dgl=0;  
    }

}

inline void bfs()
{
    while(l<=r)
    {
        int x=q[l++];
        //cout<<x<<' ';
        for(int i=h[x];i;i=ne[i])
        {
            int y=e[i];//cout<<y<<' '; 

            if(f[y]<f[x]+sid[y-n])
            {
                f[y]=f[x]+sid[y-n];
                g[y]=g[x];
            }
            else if(f[y]==f[x]+sid[y-n])
                g[y]=(g[x]+g[y])%mod;

            if(!st[y])
            {
                st[y]=1;
                q[r++]=y;
            }
        }

    }
    //cout<<'\n';
}

int main()
{
    cin>>n>>m>>mod;

    for(int i=1;i<=m;i++)
    {
        int a,b;
        cin>>a>>b;
        add(a,b);
    }
    for(int i=1;i<=n;i++)
      if(!st[i])
      {
        s=i;
        break;
        }
    memset(st,0,sizeof st);

    for(int i=1;i<=n;i++)
      if(!dfn[i])
        tarjan(i);

    find();

    for(int i=1;i<=scnt;i++)
        if(!rr[i])
        {
            q[r++]=i+n;
            f[i+n]=sid[i];
            g[i+n]=1;
            st[i+n]=1;
        }

/*  for(int i=1;i<=scnt;i++)
    cout<<f[i+n]<<' ';
    cout<<'\n';*/
  memset(st,0,sizeof st);    
    bfs();

    for(int i=1;i<=scnt;i++)
    //cout<<f[i+n]<<' ';
      if(!c[i])
      {
        if(ans<f[i+n])
        {
            ans=f[i+n];
            res=g[i+n];
            }
            else if(ans==f[i+n])
              res=(res+g[i+n])%mod;
        }

    cout<<ans<<'\n'<<res;

    return 0;
}

|