问题描述
一条单向的铁路线上,依次有编号为 1, 2, …, n 的 n 个火车站。每个火车站都有一个级别,最低为 1 级。现有若干趟车次在这条线路上行驶,每一趟都满足如下要求:如果这趟车次停靠了火车站 x,则始发站、终点站之间所有级别大于等于火车站 x 的都必须停靠。(注意:起始站和终点站自然也算作事先已知需要停靠的站点)例如,下表是 5 趟车次的运行情况。其中,前 4 趟车次均满足要求,而第 5 趟车次由于停靠了 3 号火车站(2 级)却未停靠途经的 6 号火车站(亦为 2 级)而不满足要求。
现有 m 趟车次的运行情况(全部满足要求) ,试推算这 n 个火车站至少分为几个不同的级别。
输入
-
第一行包含 2 个正整数 n, m,用一个空格隔开。第 i + 1 行(1 ≤ i ≤ m)中,首先是一个正整数 si (2 ≤ si≤ n),表示第 i 趟车次有 si 个停靠站;接下来有 si 个正整数,表示所有停靠站的编号,从小到大排列。每两个数之间用一个空格隔开。输入保证所有的车次都满足要求。
输入样例#1:
Case 1: 9 2 4 1 3 5 6 3 3 5 6 Case 2: 9 3 4 1 3 5 6 3 3 5 6 3 1 5 9
输出样例#1:
Case 1: 2 Case 2: 3
根据题意,可以知道,一个列车没有经过的点的分级的值都是要比自己的值要小的,于是给每一个没有经过的点和经过的点连一条有向边,运用拓扑排序的知识,找到入度为0的点,并且删除与其相连的所有边,我们可以用栈或者队列来储存时间戳也就是ans的值,这道题细节比较多,很多地方还是值得细细考虑的。1 #include<bits/stdc++.h> 2 #define maxn 1100 3 using namespace std; 4 int book[maxn][maxn],du[maxn]; 5 int n,m,x,y; 6 int ans=0; 7 int s[maxn]; 8 int judge[maxn]; 9 10 11 void topusort() 12 { 13 int num=0; 14 queue<int > q; 15 16 while(num<n) 17 { 18 for(int i=1;i<=n;i++) 19 if(du[i]==0) 20 { 21 du[i]=-1; 22 q.push(i); 23 num++; 24 } 25 ans++; 26 while(!q.empty()) 27 { 28 int k=q.front();q.pop(); 29 for(int j=1;j<=n;j++) 30 if(book[k][j]==1) 31 { 32 book[k][j]=0; 33 du[j]--; 34 } 35 } 36 } 37 } 38 39 40 void init() 41 { 42 cin>>n>>m; 43 44 while(m--) 45 { 46 int x; 47 memset(judge,0,sizeof(judge)); 48 cin>>x; 49 for(int i=1;i<=x;i++) 50 { 51 cin>>s[i]; 52 judge[s[i]]++; 53 54 } 55 for(int i=s[1];i<=s[x];i++) 56 if(!judge[i]) 57 { 58 for(int j=1;j<=x;j++) 59 book[i][s[j]]=1; 60 } 61 } 62 for(int i=1;i<=n;i++) 63 for(int j=1;j<=n;j++) 64 if(book[i][j]) 65 du[j]++; 66 } 67 68 void output() 69 { 70 cout<<ans<<endl; 71 } 72 73 int main() 74 { 75 ios::sync_with_stdio(false); 76 init(); 77 topusort(); 78 output(); 79 return 0; 80 }
总结:1.stl跑的慢不要随意使用max or min,性能差一个档次.
2.ios::sync_with_stdio(false);一旦你用cin,cout这句话无论如何都要加上,否则必须得用scanf printf或者其他的读入优化