萌新52分求调 qwq

P2272 [ZJOI2007] 最大半连通子图

Q__A__Q @ 2023-08-03 23:22:05

wa 4 5 6 7

代码:

// Problem: P2272 [ZJOI2007] 最大半连通子图
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P2272
// Memory Limit: 125 MB
// Time Limit: 2000 ms
// Author: fzy
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
// #pragma GCC optimize(2)
using namespace std;
typedef long long ll;
#define int __int128

const int maxm=1e6+10;
const int maxn=1e5+10;
const int inf=1e9+7;
int n,m,mod,ans,u[maxm],v[maxm];
int dfsnum,color,dfn[maxn],low[maxn],ins[maxn],col[maxn],sum[maxn],in[maxn];
vector<int> g[maxm],h[maxm];
int dis[maxn],vis[maxn],cnt[maxn];
int fa[maxn];

inline int read() {
    int s=0,w=1;
    char ch=getchar();
    while(!isdigit(ch)) {
        if(ch=='-')w=-1;
        ch=getchar();
    }
    while(isdigit(ch)) s=s*10+ch-'0',ch=getchar();
    return s*w;
}

inline void write(int x) {
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
}

inline void init() {
    for(int i=0;i<maxn;++i)
        fa[i]=i;
}

inline int find(int u) {
    if(fa[u]==u) return u;
    return fa[u]=find(fa[u]);
}

stack<int> s;
inline void tarjan(int u) {
    s.push(u);
    ins[u]=1;
    dfn[u]=low[u]=++dfsnum;
    for(int i=0;i<g[u].size();++i) {
        int v=g[u][i];
        if(!dfn[v]) {
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(ins[v]) low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u]) {
        ins[u]=0;
        col[u]=++color;
        sum[color]=1;
        while(s.top()!=u) {
            col[s.top()]=color;
            ins[s.top()]=0;
            sum[color]++;
            s.pop();
        }
        s.pop();
    }
}

queue<int> q;
inline void topsort() {
    memset(dis,0,sizeof dis);
    memset(vis,0,sizeof vis);
    for(int i=1;i<=color;++i) {
        if(!in[i]) q.push(i),dis[i]=sum[i],cnt[i]=1;//cout<<i<<endl;
    }
    while(!q.empty()) {
        int u=q.front();
        q.pop();
        for(int i=0;i<h[u].size();++i) {
            int v=h[u][i];
            if(dis[v]==dis[u]+sum[v]) {
                cnt[v]=(cnt[v]+cnt[u])%mod;
            }
            else if(dis[v]<dis[u]+sum[v]) {
                dis[v]=dis[u]+sum[v];
                cnt[v]=cnt[u];
            }
            if(--in[v]==0) q.push(v);
        }
    }
}

signed main() {
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    n=read(),m=read(),mod=read();
    for(int i=1;i<=m;++i) {
        u[i]=read(),v[i]=read();
        g[u[i]].push_back(v[i]);
    }
    for(int i=1;i<=n;++i) 
        if(!dfn[i]) tarjan(i);
    // for(int i=1;i<=n;++i) cout<<col[i]<<endl;
    init();
    for(int i=1;i<=m;++i) {
        if(col[u[i]]==col[v[i]]) continue;
        int uu=col[u[i]],vv=col[v[i]];
        if(find(uu)==find(vv)) continue;
        fa[find(uu)]=find(vv);
        in[col[v[i]]]++;
        h[col[u[i]]].push_back(col[v[i]]);
    }
    topsort();
    int mx=-inf;
    for(int i=1;i<=color;++i) {
        if(dis[i]>mx) mx=dis[i];
    }
    for(int i=1;i<=color;++i)
        if(dis[i]==mx) ans=(ans+cnt[i])%mod;
    write(mx),puts("");
    write(ans);
    return 0;
}

by Q__A__Q @ 2023-08-03 23:36:49

用并查集判断重边可以吗??


|