Tarjan 52pts 求调 已删去重边
查看原帖
Tarjan 52pts 求调 已删去重边
572133
潘德理2010楼主2023/11/5 22:33
#include<bits/stdc++.h>
using namespace std;
int n,m,x,a,b,te;
int l[100100],d[100100],in[100100],s[100100],c,t,sz[100100],f[100100],g[100100],mans,ans,pt[100100];
stack<int> st;
priority_queue<int,vector<int>,greater<int> > q[100100];
vector<int> e[100100],k[100100];
queue<int> tpo,r;
void tarj(int u){
	l[u]=d[u]=++c;
	st.push(u);
	in[u]=1;
	for(int i=0;i<int(e[u].size());i++){
		int v=e[u][i];
		if(!d[v]){
			tarj(v);
			l[u]=min(l[u],l[v]);
		}
		else if(in[v]){
			l[u]=min(l[u],l[v]);
		}
	}
	if(l[u]==d[u]){
		++t;
		while(1){
			s[st.top()]=t;
			in[st.top()]=0;
			if(st.top()==u){
				st.pop();
				break;
			}
			st.pop();
		}
	}
}
int main(){
	scanf("%d%d%d",&n,&m,&x);
	for(int i=1;i<=m;i++){
		scanf("%d%d",&a,&b);
		e[a].push_back(b);
	}
	for(int i=1;i<=n;i++){
		if(!d[i]) tarj(i);
	}
	for(int i=1;i<=n;i++){
		for(int j=0;j<int(e[i].size());j++){
			if(s[i]!=s[e[i][j]]) q[s[i]].push(s[e[i][j]]);
		} 
	}
	for(int i=1;i<=n;i++){
		sz[s[i]]++;
	}
	n=t;
	for(int i=1;i<=n;i++){
		while(!q[i].empty()){
			te=q[i].top();
			k[i].push_back(te);
			pt[te]++;
			while(!q[i].empty()){
				if(q[i].top()==te) q[i].pop();
				else break;
			}
		}
	}
	for(int i=1;i<=n;i++){
		if(pt[i]==0) tpo.push(i),f[i]=sz[i],mans=max(mans,f[i]),g[i]=1;
	}
	while(!tpo.empty()){
		int u=tpo.front();
		tpo.pop();
		for(int i=0;i<int(k[u].size());i++){
			int v=k[u][i];
			pt[v]--;			
			if(f[v]<f[u]+sz[v]){
				f[v]=f[u]+sz[v];
				g[v]=g[u]%x;
			} 
			else if(f[v]==f[u]+sz[v]){
				g[v]=(g[v]+g[u])%x;
			}
			tpo.push(v);
			mans=max(mans,f[v]);
		}
	}
	for(int i=1;i<=n;i++){
		if(f[i]==mans) ans=(ans+g[i])%x;
	}
	printf("%d\n%d",mans,ans);
	return 0;
}
2023/11/5 22:33
加载中...