[题解]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;
}
浙公网安备 33010602011771号