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
用并查集判断重边可以吗??