[题解]P1983 [NOIP 2013 普及组] 车站分级

P1983 [NOIP 2013 普及组] 车站分级

对于一趟车次停靠的位置\(p_1,p_2,\dots,p_s\),可以确定的是\([p_1,p_s]\)中除\(p\)以外的位置,优先级一定低于这些\(p\)

对于\(a,b\)两个点,若\(a\)的优先级低于\(b\),就添加一条\(a\rightarrow b\)的边(反过来也可以)。

由于输入合法,最终形成的图一定是一个DAG,拓扑排序求得其高度,即为答案。

显然边数上界是\(n^2\),需要用\(vis\)数组去一下重边。

时间复杂度\(O(mn^2)\)

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e3+10,M=1e3+10;
int n,m,p[N],deg[N],d[N],ans;
queue<int> q;
bitset<N> vis[N];
vector<int> G[N];
signed main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n>>m;
	for(int i=1,s;i<=m;i++){
		cin>>s;
		for(int j=1;j<=s;j++) cin>>p[j];
		for(int j=1;j<s;j++){
			for(int k=p[j]+1;k<p[j+1];k++){
				for(int l=1;l<=s;l++) if(!vis[k][p[l]]) vis[k][p[l]]=1,G[k].emplace_back(p[l]),deg[p[l]]++;
			}
		}
	}
	for(int i=1;i<=n;i++){
		if(!deg[i]) q.push(i);
		d[i]=1; 
	}
	while(!q.empty()){
		int u=q.front();
		q.pop();
		for(int i:G[u]){
			d[i]=max(d[i],d[u]+1);
			deg[i]--;
			if(!deg[i]) q.push(i);
		}
	}
	for(int i=1;i<=n;i++) ans=max(ans,d[i]);
	cout<<ans<<"\n";
	return 0;
}
posted @ 2025-07-10 14:34  Sinktank  阅读(53)  评论(0)    收藏  举报
★CLICK FOR MORE INFO★ TOP-BOTTOM-THEME
Enable/Disable Transition
Copyright © 2023 ~ 2025 Sinktank - 1328312655@qq.com
Illustration from 稲葉曇『リレイアウター/Relayouter/中继输出者』,by ぬくぬくにぎりめし.