- [ZJOI2007] 最大半连通子图
@ZCY
- 2025-7-3 20:42:58 @
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+2;
int n,m,mod;
vector<int>g[N];
int dfn[N],dfn_tot=0;
int low[N];
vector<int>scc[N];
int scc_tot=0;
stack<int>stk;
bool stk_vis[N];
int belong[N];
int scc_size[N];
void Tarjan(int u)
{
dfn[u]=low[u]=++dfn_tot;
stk.push(u),stk_vis[u]=1;
for(auto v:g[u])
{
if(!dfn[v])Tarjan(v),low[u]=min(low[u],low[v]);
else if(stk_vis[v])low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u])
{
scc_tot++;
int v;
do
{
v=stk.top();
stk.pop(),stk_vis[v]=0;
scc[scc_tot].push_back(v);
belong[v]=scc_tot;
}while(u!=v);
}
}
set<int>sccg[N];
void built_sccg()
{
for(int u=1;u<=n;u++)
for(auto v:g[u])
if(belong[u]!=belong[v])
sccg[belong[u]].insert(belong[v]);
}
bool getmax_vis[N];
int getmax(int u)
{
if(getmax_vis[u])return scc_size[u];
getmax_vis[u]=1;
for(auto v:sccg[u])
scc_size[u]=max(scc_size[u],getmax(v));
scc_size[u]+=scc[u].size();
return scc_size[u];
}
int mem[N];
int dfs(int u)
{
if(mem[u])return mem[u];
for(auto v:g[u])
if(scc_size[u]==scc_size[v]+scc[u].size())
mem[u]=(mem[u]+dfs(v))%mod;
if(!mem[u])mem[u]=1;
return mem[u];
}
signed main()
{
cin>>n>>m>>mod;
for(int i=1;i<=m;i++)
{
int u,v;cin>>u>>v;
g[u].push_back(v);
}
for(int i=1;i<=n;i++)
if(!dfn[i])Tarjan(i);
built_sccg();
int ma=0,sum=0;
for(int i=1;i<=scc_tot;i++)
ma=max(ma,getmax(i));
for(int i=1;i<=scc_tot;i++)
if(ma==scc_size[i])
sum=(sum+dfs(i))%mod;
cout<<ma<<"\n"<<sum;
return 0;
}
2 comments
-
C24zhuchengyu LV 8 @ 2025-7-3 20:49:28
啊啊啊,我知道了!
你的
dfs()
应该用sccg
找,但是你用了g
。在
dfs()
的第4行 -
2025-7-3 20:47:36@
不是我寻思着你这和我的一摸一样为啥你错了???
怀疑是
getmax()
的问题,可能设错了
- 1
Information
- ID
- 421
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- 8
- Tags
- # Submissions
- 61
- Accepted
- 8
- Uploaded By