- [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 C24zhuchengyu LV 8 @ 2025-7-3 20:49:28啊啊啊,我知道了! 你的 dfs()应该用sccg找,但是你用了g。在 dfs()的第4行
- 
   @ 2025-7-3 20:47:36 @ 2025-7-3 20:47:36不是我寻思着你这和我的一摸一样为啥你错了??? 怀疑是 getmax()的问题,可能设错了
- 1
Information
- ID
- 421
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- 8
- Tags
- # Submissions
- 61
- Accepted
- 8
- Uploaded By
 
      