• 题解:车站分级(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 }
  • 相关阅读:
    利用CWinThread实现跨线程父子MFC窗口
    GetForgroundWindow函数的不确定性——BUG笔记
    DLL动态链接库的创建
    php正则讲解 及与 js的正则比较
    cookie和session的讲解
    两种排序的方法 冒泡法 插入法 封装版
    php中获取当前时间
    文件下载及header方法介绍
    文件上传
    二分法封装版
  • 原文地址:https://www.cnblogs.com/Aze-qwq/p/9894062.html
Copyright © 2020-2023  润新知