缩点+分层图+拓扑求调教
查看原帖
缩点+分层图+拓扑求调教
754502
_AyachiNene楼主2024/3/25 17:19
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
	int res=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
	while(c>='0'&&c<='9'){res=(res<<1)+(res<<3)+(c^48);c=getchar();}
	return res*f;
}
void write(int x)
{
	if(x<0){x=-x;putchar('-');}
	if(x>9) write(x/10);
	putchar(x%10+'0');
}
struct node
{
	int nxt,to;
}e[1145141];
int head[1145141],cnt_edge;
void add_edge(int u,int v)
{
	e[++cnt_edge].to=v;
	e[cnt_edge].nxt=head[u];
	head[u]=cnt_edge;
}
int dfn[114514],low[114514],cnt,vis_stk[114514],scc[114514],cnt_scc;
int stk[114514],top;
void tarjan(int u)
{
	dfn[u]=low[u]=++cnt;
	vis_stk[u]=1;
	stk[++top]=u;
	for(int i=head[u];i;i=e[i].nxt)
	{
		int v=e[i].to;
		if(!dfn[v])
		{
			tarjan(v);
			low[u]=min(low[u],low[v]);
		}
		else if(vis_stk[v]) low[u]=min(low[u],dfn[v]);
	}
	if(dfn[u]==low[u])
	{
		++cnt_scc;
		while(stk[top+1]!=u) scc[stk[top]]=cnt_scc,vis_stk[stk[top--]]=0;
	}
}
pair<int,int>edge[114514];
int n,m;
int dp[1145141];
int deg[1145141];
int w[114514];
void top_sort()
{
	queue<pair<int,int> >q;
	for(int i=1;i<=cnt_scc*3;i++)
		if(!deg[i]) q.push(make_pair(i,0)),dp[i]=w[i];
	while(q.size())
	{
		int u=q.front().first,step=q.front().second;
		q.pop();
		if(u>cnt_scc&&u<=2*cnt_scc) ++step;
		for(int i=head[u];i;i=e[i].nxt)
		{
			int v=e[i].to;
			if(step>1&&v>cnt_scc&&v<=2*cnt_scc) continue;
			dp[v]=max(dp[v],dp[u]+w[v]);
			if(--deg[v]==0) q.push(make_pair(v,step));
		}
	}
}
int main()
{
	n=read(),m=read();
	for(int i=1;i<=m;i++)
	{
		int u=read(),v=read();
		add_edge(u,v);
		edge[i].first=u,edge[i].second=v;
	}
	for(int i=1;i<=n;i++)
		if(!dfn[i]) tarjan(i);
	for(int i=1;i<=n;i++) ++w[scc[i]];
	memset(head,0,sizeof head);
	cnt_edge=0;
	for(int i=1;i<=cnt_scc;i++)
		for(int j=1;j<=2;j++)
			add_edge(scc[i]+cnt_scc*(j-1),scc[i]+cnt_scc*j),++deg[scc[i]+cnt_scc*j];
	for(int i=1;i<=m;i++)
	{
		int u=edge[i].first,v=edge[i].second;
		if(scc[u]==scc[v]) continue;
		add_edge(scc[v],scc[u]);
		add_edge(scc[u]+cnt_scc,scc[v]+cnt_scc);
		add_edge(scc[v]+cnt_scc*2,scc[u]+cnt_scc*2);
		++deg[scc[u]];
		++deg[scc[v]+cnt_scc];
		++deg[scc[u]+cnt_scc*2];
	}
	top_sort();
	write(max(dp[scc[1]],dp[scc[1]+cnt_scc*2]));
}
2024/3/25 17:19
加载中...