萌新刚学OI,76分求助

P2272 [ZJOI2007] 最大半连通子图

谦谦君子 @ 2019-08-18 11:58:02

dalao们帮忙看一下呀!

#include<bits/stdc++.h>
using namespace std;
int n,m,mx,res,top,ex,cnt,h,t,ans,kt,u;
int x[1000001],y[1000001],fir[100001],nex[1000001],ft[100001],inx[100001],to[1000001],las[100001],ru[1000001],ins[100001],f[100001],DFN[100001],low[100001],st[100001],cn[100001],rst[100001];
inline int read()
{
    int x=0;
    char c;
    for(c=getchar();c<'0'||c>'9';c=getchar());
    while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
    return x;
}
void add(int x,int y)
{
    kt++;
    nex[kt]=fir[x];
    fir[x]=kt;
    to[kt]=y;
}
void tarjan(int x)
{
    int v;
    DFN[x]=low[x]=++ex;
    st[++top]=x;
    for (int p=fir[x];p;p=nex[p])
    {
        if (!DFN[to[p]])
        {
            tarjan(to[p]);
            low[x]=min(low[x],low[to[p]]);
        }
        else if(!cn[to[p]])low[x]=min(low[x],DFN[to[p]]);
    }
    if (low[x]==DFN[x])
    {
        cn[x]=++cnt;ins[cnt]++;
        while (st[top]!=x)
        {
            cn[st[top]]=cnt,top--,ins[cnt]++;
        }
        top--;
    }
}
bool cmp(int a,int b)
{
    if (x[a]!=x[b])
    {
        return x[a]<x[b];return y[a]<y[b];
    }
}
inline void del()
{
    for (int i=1;i<=m;i++)
    {
        if ((x[ru[i]]!=y[ru[i]])&&(x[ru[i]]!=x[ru[i-1]]||y[ru[i]]!=y[ru[i-1]]))
        {
            ft[y[ru[i]]]++;
            add(x[ru[i]],y[ru[i]]);
        }
    }
}
int main()
{
    n=read();m=read();mx=read();
    for (int i=1;i<=m;i++)
    {
        x[i]=read(),y[i]=read();
        add(x[i],y[i]);
    }
    for (int i=1;i<=n;i++)
    {
        if (!DFN[i])
        {
            tarjan(i);
        }
    }
    for (int i=1;i<=m;i++)
    {
        ru[i]=i;
        x[i]=cn[x[i]],y[i]=cn[y[i]];
    }
    sort(ru+1,ru+1+m,cmp);
    kt=0;
    memset(fir,0,sizeof(fir));
    del();
    for (int i=1;i<=cnt;i++)
    {
        if (!ft[i])
        {
            rst[++t]=i;
            f[i]=ins[i];
            inx[i]=1;
            if (f[ans]<f[i])
            {
                ans=i;
            }
        }
        while (h<t)
        {
            h++;
            u=rst[h];
            for (int p=fir[u];p;p=nex[p])
            {
                ft[to[p]]--;
                if (f[to[p]]<f[u]+ins[to[p]])
                {
                    f[to[p]]=f[u]+ins[to[p]];

                    inx[to[p]]=0;
                    if (f[ans]<f[to[p]])
                    {
                        ans=to[p];
                    }
                }
                if (f[to[p]]==f[u]+ins[to[p]])
                {
                    inx[to[p]]=(inx[to[p]]+inx[u])%mx;
                }
                if (!ft[to[p]])
                {
                    rst[++t]=to[p];
                }
            }
        }
    }
    for (int i=1;i<=n;i++)
    {
        if(f[i]==f[ans])
        {
            res=(res+inx[i])%mx;
        }
    }
    printf("%d\n%d",f[ans],res);
    return 0;
}

by Provicy @ 2019-08-18 11:59:09

%%%完全没学过qwq


|