problem
- 给定n个车站(依次编号从1到n,并且有一个优先级),m趟车次(每次停靠的站点)
- 满足每一趟车次中,如果停靠了x,那么这一趟车次中所有优先级>=x的都要停。(始发站和终点站自然也要停另说)
- 求最少有多少个优先级。
solution
- 因为所有>=x的都要停,所以没停的都是优先级小于x的,即一趟车次中没停的站点的优先级要小于这趟车次的每一个停靠站。(因为这一趟车次停靠站之间的相对大小不知道,不能拿那个算。)
- 于是就可以得到车站之间的大小关系。从小的(所有没停的)向大的(所有停了的)都连一条边。拓扑排序统计有几层(开pair加一而不是节点遇到入度0的原因是入度相同的节点可能不唯一,他们可以是一个层级的,就会有重复统计的问题)。
codes
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;
const int maxn = 1010;
int ting[maxn], vis[maxn];
vector<int>G[maxn]; int in[maxn]; int book[maxn][maxn];
int main(){
int n, m; cin>>n>>m;
for(int i = 1; i <= m; i++){
memset(vis,0,sizeof(vis));
int x; cin>>x;
for(int j = 1; j <= x; j++){ cin>>ting[j]; vis[ting[j]]=1;}
for(int j = ting[1]; j <= ting[x]; j++){
if(vis[j])continue;
for(int k = 1; k <= x; k++)
{
if(book[j][ting[k]])continue;
else book[j][ting[k]] = 1;
G[j].push_back(ting[k]); in[ting[k]]++;
}
}
}
int ans = 1;
queue<pair<int, int> >q;
for(int i = 1; i <= n; i++)if(in[i]==0)q.push(make_pair(i,1));
while(q.size()){
int u = q.front().first, v = q.front().second; q.pop();
for(int i = 0; i < G[u].size(); i++)
if(--in[G[u][i]] == 0){q.push(make_pair(G[u][i],v+1));ans = max(ans,v+1);}
}
cout<<ans<<'
';
return 0;
}