蒟蒻64pts求助 WA#4#5#7

P2272 [ZJOI2007] 最大半连通子图

daitouzero @ 2023-01-16 16:34:27

就是先拿Tarjon缩点再拓补排序

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<bitset>
#include<vector>
#include<set>
#define X 20005
#define ll long long
#define MOD 998244353
using namespace std;
inline int Max(int a,int b) {return a>b?a:b;}
inline int Min(int a,int b) {return a<b?a:b;}
inline void Swap(int &a,int &b) {a=a^b;b=a^b;a=a^b;}
inline int scan()
{
    register int x=0,f=0;
    register char c=getchar();
    while(c<'0') f|=(c=='-'),c=getchar();
    while(c>='0') x=(x<<1)+(x<<3)+(c&15),c=getchar();
    return f?-x:x;
}
inline void print(int x,char c)
{
    if (x<0) {x=-x;putchar('-');}
    if(x/10) print(x/10,0); 
    putchar(x%10+48);
    if (c) putchar(c);
}
int n,m,x;
vector<int>edge[1000005];
set<int>point[1000005];
int size[1000005];
int dfn[1000005],low[1000005],Time;
bool instack[1000005];
int top,stack[1000005];
int color,col[1000005];
void Tarjon(int s)
{
    instack[s]=true;
    top++;
    stack[top]=s;
    Time++;
    dfn[s]=Time;
    low[s]=dfn[s];
    for (int i=0,Next;i<edge[s].size();i++)
    {
        Next=edge[s][i];
        if (dfn[Next]==0) 
        {
            Tarjon(Next);
            low[s]=Min(low[s],low[Next]);
        }
        else if (instack[Next]) low[s]=Min(low[s],dfn[Next]);
    }
    if (dfn[s]==low[s])
    {
        int pos;
        color++;
        do 
        {
            pos=stack[top];top--;
            instack[pos]=false;
            col[pos]=color;
            size[color]++;
        }while (pos!=s);
    }
}
int in[1000005],dist[1000005];
int longlink,waycnt[1000005],longlinkcnt;
int head,tail,dl[1000005];
inline void Topsort()
{
    int pos;
    set<int>::iterator Next;
    while (head<tail)
    {
        head++;
        pos=dl[head];
        for (Next=point[pos].begin();Next!=point[pos].end();Next++)
        {
            if (dist[pos]+size[*Next]>dist[*Next])
            {
                dist[*Next]=dist[pos]+size[*Next];
                waycnt[*Next]=waycnt[pos];
            }
            else if (dist[pos]+size[*Next]==dist[*Next])
            {
                waycnt[*Next]+=waycnt[pos];
                waycnt[pos]%=x;
            }
            in[*Next]--;
            if (in[*Next]==0) tail++,dl[tail]=*Next;
        }
    }
}
int main()
{
    n=scan();m=scan();x=scan();
    for (int i=1,u,v;i<=m;i++)
    {
        u=scan();v=scan();
        edge[u].push_back(v);
    }
    for (int i=1;i<=n;i++)
        if (dfn[i]==0) Tarjon(i);
    for (int i=1;i<=n;i++)
        for (int e=0,Next;e<edge[i].size();e++)
        {
            Next=edge[i][e];
            if (col[i]!=col[Next])
            {
                point[col[i]].insert(col[Next]);
                in[col[Next]]++;
            }
        }
    //print(color,'\n');
    for (int i=1;i<=color;i++)
    {
        if(in[i]==0) tail++,dl[tail]=i;
        waycnt[i]=1;dist[i]=size[i];
    }
    Topsort();
    for (int i=1;i<=n;i++)
    {
        if (longlink<dist[i])
        {
            longlink=dist[i];
            longlinkcnt=waycnt[i];
        }
        else if (longlink==dist[i])
            longlinkcnt=(longlinkcnt+waycnt[i])%x;
    }
    print(longlink,'\n');
    print(longlinkcnt,'\n');
    return 0;
}

by daitouzero @ 2023-01-16 22:31:04

破案了

重边判了but统计入度的时候把重边一起算了

此贴完结


|