zoukankan      html  css  js  c++  java
  • [NOIp2013普及组]车站分级

    思路:

    对于每一趟车,将区间内所有经停的站和所有未经停的站连一条边,表示前者优先级一定高于后者,然后用Kahn跑一遍拓扑排序即可。然而这样会创造大量多余的边,会TLE1个点。
    考虑一种优化:因为每趟车本身也有一个优先级,因此可以将这趟车也看作一个点,每次先所有将经停的站连一条边到这两车上,表示这些站的优先级一定大于等于车的优先级,再将车连若干边到未经停的点,表示车的优先级一定大于未经停的站的优先级。

     1 #include<queue>
     2 #include<cstdio>
     3 #include<cctype>
     4 #include<cstring>
     5 inline int getint() {
     6     register char ch;
     7     while(!isdigit(ch=getchar()));
     8     register int x=ch^'0';
     9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    10     return x;
    11 }
    12 const int N=2001,M=1000001;
    13 struct List {
    14     int to,next;
    15 };
    16 List e[M];
    17 int sz=0;
    18 int h[N]={0};
    19 int in[N]={0};
    20 inline void add_edge(const int u,const int v) {
    21     e[++sz]=(List){v,h[u]};
    22     h[u]=sz;
    23     in[v]++;
    24 }
    25 const int inf=0x7fffffff;
    26 int ans=0;
    27 int n,m;
    28 inline void kahn() {
    29     std::queue<std::pair<int,int> > q;
    30     for(register int i=1;i<=n;i++) {
    31         if(!in[i]) q.push(std::make_pair(i,1));
    32     }
    33     while(!q.empty()) {
    34         int x=q.front().first,d=q.front().second;
    35         q.pop();
    36         for(register int i=h[x];i;i=e[i].next) {
    37             if(!--in[e[i].to]) {
    38                 q.push(std::make_pair(e[i].to,d+1));
    39             }
    40         }
    41         ans=std::max(ans,d);
    42     }
    43 }
    44 int main() {
    45     n=getint(),m=getint();
    46     int b[n+1];
    47     for(register int i=1;i<=m;i++) {
    48         memset(b,0,sizeof b);
    49         int s=getint();
    50         int S=getint();
    51         b[S]=true;
    52         for(register int j=2;j<s;j++) {
    53             b[getint()]=true;
    54         }
    55         int T=getint();
    56         b[T]=true;
    57         for(register int j=S;j<=T;j++) {
    58             if(b[j]) {
    59                 add_edge(j,i+n);
    60             }
    61             else {
    62                 add_edge(i+n,j);
    63             }
    64         }
    65     }
    66     kahn();
    67     printf("%d
    ",(ans+1)>>1);
    68     return 0;
    69 }
  • 相关阅读:
    hdu 5001 从任意点出发任意走d步不经过某点概率
    hdu 5007
    hdu 5009 离散化
    hdu 5011 Nim+拿完分堆
    thinkphp 删除多条记录
    thinkphp 实现无限极分类
    图片生成唯一的名字
    html 标签学习
    PHP比较运算!=和!==
    php使用 set_include_path
  • 原文地址:https://www.cnblogs.com/skylee03/p/7306216.html
Copyright © 2011-2022 走看看