题解:车站分级(2013普及组)

这道题可以暴力可以拓扑排序

甚至还可以差分约束????

原谅我一开始没看出来可以差分约束

这是暴力做法

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 int f[1010][1010], a[1010];//f数组记录每趟车次停靠的站点,a数组记第i个车站的分级
 6 bool by[1010][1010];//表示第i趟车是否在j站停靠,true表示停靠
 7 int n, m, maxn;
 8 int main(){
 9     cin>>n>>m;
10     memset(by,false,sizeof(by));
11     for(int i=1; i<=n; i++){
12         a[i]=1;
13     }
14     for(int i=1; i<=m; i++){
15         cin>>f[i][0];
16         for(int j=1; j<=f[i][0]; j++){
17             cin>>f[i][j];
18             by[i][f[i][j]]=true;
19         }
20     }
21     while(1){
22         bool judge=false;
23         for(int i=1; i<=m; i++){
24             maxn=0;
25             for(int j=f[i][1]; j<=f[i][f[i][0]]; j++){
26                 if(by[i][j]==false) maxn=max(a[j], maxn);//记录不停靠的最大值
27             }
28             maxn++;//停靠的一定比不停靠的至少打1
29             for(int j=1; j<=f[i][0]; j++){
30                 if(a[f[i][j]]<maxn){ 
31                     a[f[i][j]]=maxn;
32                     judge=true;
33                 }
34             }
35         }
36         if(!judge) break;//没有更新过就跳出
37     }
38     maxn=0;
39     for(int i=1; i<=n; i++){
40         maxn=max(a[i],maxn);
41     }
42     cout<<maxn<<endl;
43     return 0;
44 }

这是拓扑的做法

把没有停靠过的车站连一条有向边到停靠过的车站。没有停靠过的从下面向上指向停靠过的,等级比上面的低。

那么每有一层就代表有一个等级,不断地断边,每断掉一层就ans++

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 int s[1005], degree[1005], topo[1005];//s记录停靠的车站,degree表示类似于入度的东西,topo为记录数组
 6 bool is[1005], edge[1005][1005], vis[1005];//is表示是否停靠,edge表示是否从i到j连边, vis表示是否在topo数组里
 7 int n, m, ans, top;
 8 int main(){
 9     cin>>n>>m;
10     for(int i=1; i<=m; i++){
11         memset(is, false, sizeof(is));
12         cin>>s[0];
13         for(int j=1; j<=s[0]; j++){
14             cin>>s[j];
15             is[s[j]]=true;
16         }
17         for(int j=s[1]; j<=s[s[0]]; j++){
18             if(!is[j]){
19                 for(int k=1; k<=s[0]; k++){
20                     if(!edge[j][s[k]]){
21                         edge[j][s[k]]=true;
22                         degree[s[k]]++;
23                     }
24                 }
25             }
26         }
27     }
28     do{
29         top=0;
30         for(int i=1; i<=n; i++){
31             if(!degree[i] && !vis[i]){
32                 topo[++top]=i;
33                 vis[i]=true;
34             }
35         }
36         for(int i=1; i<=top; i++){
37             for(int j=1; j<=n; j++){
38                 if(edge[topo[i]][j]){
39                     edge[topo[i]][j]=false;
40                     degree[j]--;
41                 }
42             }
43         }
44         ans++;
45     }while(top);
46     --ans;
47     cout<<ans<<endl;
48     return 0;
49 }

猜你喜欢

转载自www.cnblogs.com/Aze-qwq/p/9894062.html