70pts求调
查看原帖
70pts求调
1034667
Elysian_Realme楼主2024/1/19 09:03
// Problem:
//     P3436 [POI2006] PRO-Professor Szu
//   
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3436
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// 
// AC Date:2024-01-19
// By:lmq

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1000006;
struct edge{
	int u,v,nxt;
}mp[maxn];
int n,m,top,cnt,tim;
int rd[maxn];
int dp[maxn],idx[maxn];
int dfn[maxn],low[maxn];
int col[maxn],colnum[maxn];
bool h[maxn],vis[maxn];stack <int> stk;
void add(int u,int v){
	mp[++top].u=u;
	mp[top].v=v;
	mp[top].nxt=idx[u];
	idx[u]=top;
}
void dfs(int u){
	bool huan=0;
	dfn[u]=low[u]=++tim;
	vis[u]=1,stk.push(u);
	for(int i=idx[u];i!=0;i=mp[i].nxt){
		int v=mp[i].v;
		if(u==v)huan=1;
		if(!dfn[v]){
			dfs(v);
			low[u]=min(low[u],low[v]);
		}else if(vis[v])
			low[u]=min(low[u],dfn[v]);
	}
	if(low[u]==dfn[u]){
		int p;cnt++;
		do{
			p=stk.top();
			col[p]=cnt,colnum[cnt]++;
			vis[p]=0,stk.pop();
		}while(p!=u);
		if(huan||colnum[cnt]>1)h[cnt]=1;
	}
}
void tarjan(){
	for(int i=1;i<=n+1;i++)
		if(!dfn[i])
			dfs(i);
}
void topo(){
	dp[col[n+1]]=1;
	queue <int> que;
	for(int i=1;i<=cnt;i++)
		if(!rd[col[i]]&&col[n+1]!=i)
			que.push(col[i]);
	while(!que.empty()){
		int u=que.front();
		que.pop();
		for(int i=idx[u];i!=0;i=mp[i].nxt){
			int v=mp[i].v;
			if(!--rd[v])que.push(v);
		}
	}
	que.push(col[n+1]);
	while(!que.empty()){
		int u=que.front();que.pop();
		if(h[u])dp[u]=36501;
		for(int i=idx[u];i!=0;i=mp[i].nxt){
			int v=mp[i].v;
			dp[v]=min(dp[v]+dp[u],36501);
			if(!--rd[v])que.push(v);
		}
	}
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int u,v;cin>>u>>v;
		add(v,u);
	}
	tarjan();
	int x=top;top=0;memset(idx,0,sizeof(idx));
	for(int i=1;i<=x;i++)
		if(col[mp[i].u]!=col[mp[i].v])
			add(col[mp[i].u],col[mp[i].v]),rd[col[mp[i].v]]++;
	topo();
	int ans=0,num;
	for(int i=1;i<=cnt;i++)
		ans=max(ans,dp[i]);
	if(ans==36501)cout<<"zawsze"<<endl;
	else cout<<ans<<endl;
	for(int i=1;i<=cnt;i++)
		if(dp[i]==ans)num+=colnum[i];
	if(dp[col[n+1]]==ans)num--;
	cout<<num<<endl;
	for(int i=1;i<=n;i++)
		if(dp[col[i]]==ans)
			cout<<i<<" ";
	return 0;
}

2024/1/19 09:03
加载中...