NOIP2013普及组第四题(洛谷P1983) 车站分级

洛谷P1983 车站分级

题意:

  一条单向的铁路线上,依次有编号为 1,2,…,n1, 2, …, n 1,2,,nnn n个火车站。每个火车站都有一个级别,最低为 111 级。现有若干趟车次在这条线路上行驶,每一趟都满足如下要求:如果这趟车次停靠了火车站 xxx,则始发站、终点站之间所有级别大于等于火车站x xx 的都必须停靠。(注意:起始站和终点站自然也算作事先已知需要停靠的站点)

例如,下表是5 5 5趟车次的运行情况。其中,前4 44 趟车次均满足要求,而第 555 趟车次由于停靠了 333 号火车站(222 级)却未停靠途经的 666 号火车站(亦为 222 级)而不满足要求。

思路:

  拓扑排序。

  对于每一个列车,他所停在的站点一定比这列列车经过而没有停留的站点的级别高,所以由停在的站点向经过但没有停留的站点发出一条有向边。

  将每一个列车都这样处理,然后进行拓扑排序

  排序后的拓扑图有几层答案就是几

我的错误:o(╥﹏╥)o

  1、每一个列车停车表中的第一个站点和最后一个站点分别是起点和终点,列车只会经过起点和终点之间的点,一开始没看题,结果被坑了、、、

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <queue>
 6 using namespace std;
 7 #define MAXN 1010
 8 #define MAXM 1000010
 9 struct Node{
10     int u,v;
11     Node(){}
12     Node(int u,int v):u(u),v(v){}
13 }p[MAXM];
14 int head[MAXN],Next[MAXM],du[MAXN],temp1[MAXN],temp2[MAXN],tmp[2][MAXN];
15 bool vis[MAXN],seg[MAXN][MAXN];
16 int i,j,k,m,n,tot,u,v,cnt;
17 char readc;
18 bool flag;
19 void addNode(int u,int v){
20     p[++tot]=Node(u,v);
21     Next[tot]=head[u],head[u]=tot;
22 }
23 void read(int &n){
24     while((readc=getchar())<48||readc>57);
25     n=readc-48;
26     while((readc=getchar())>=48&&readc<=57) n=n*10+readc-48;
27 }
28 int main(){
29     memset(seg,0,sizeof(seg));
30     read(n); read(m);
31     for(i=1;i<=n;i++) head[i]=-1;
32     tot=-1;
33     memset(du,0,sizeof(du));
34     for(i=1;i<=m;i++){
35         read(k); 
36         cnt=0;
37         for(j=1;j<=n;j++) vis[j]=false;
38         for(j=1;j<=k;j++){
39             read(u);
40             temp1[j]=u;
41             vis[u]=true;
42         }
43         for(j=1;j<=n;j++)
44             if(!vis[j]) temp2[++cnt]=j;
45         for(register int r=temp1[1];r<=temp1[k];r++){
46             if(vis[r]) continue;
47             for(j=1;j<=k;j++){
48                 if((!vis[r])&&(!seg[temp1[j]][r])){
49                     seg[temp1[j]][r]=true;
50                     addNode(temp1[j],r);
51                     du[r]++;
52                 }
53             }
54         }
55     }
56     /*for(i=1;i<=n;i++){
57         for(j=head[i];j+1;j=Next[j]) du[p[j].v]++;
58     }*/
59     cnt=0;
60     tmp[0][0]=tmp[1][0]=0;
61     for(i=1;i<=n;i++) if(!du[i]) tmp[0][++tmp[0][0]]=i;
62     flag=true;
63     cnt=0;
64     while(tmp[!flag][0]){
65         cnt++;
66         tmp[flag][0]=0;
67         flag=!flag;
68         for(i=1;i<=tmp[flag][0];i++){
69             for(j=head[tmp[flag][i]];j+1;j=Next[j]){
70                 du[p[j].v]--;
71                 if(!du[p[j].v]) tmp[!flag][++tmp[!flag][0]]=p[j].v;
72             }
73         }
74     }
75     printf("%d\n",cnt);
76     return 0;
77 }

 

转载于:https://www.cnblogs.com/linxif2008/p/9741098.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值