zoukankan      html  css  js  c++  java
  • NOIp2013 车站分级 【拓扑排序】By cellur925

    题目传送门

    我们注意到,题目中说:如果这趟车次停靠了火车站 x,则始发站、终点站之间所有级别大于等于火车站x的都必须停靠。有阶级关系,满满的拓扑排序氛围。但是,如果我们按大于等于的关系连,等于的情况就会连双向边,这不利于我们在有向无环图中(DAG)进行拓扑排序。于是我们不妨换一种思路,将所有小于当前火车站级别的车站向输入的车站序列间连一条有向边。之后边拓扑排序边更新车站级数即可。

    注意建图的细节过程。首先对于每个车次,我们应该从起点出发终点结束,也就是代码中的w[1]和w[n];其次由于有很多车次 ,所以可能发生建了重边的情况,所以另需要数组来记录边 有没有被连过。

    在进行拓扑排序时,将一个pair插入队列,入度为0的点一定级别最低 ,它为1,对于每个从它出发得到的点,我们把它的级别+1即可。

    同杂务一题一样,拓扑保证最小性质,而取max保证考虑全面。

    Code

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<queue>
     5 #include<utility>
     6 
     7 using namespace std;
     8 
     9 int n,m,tot,ans;
    10 int head[1009],du[1009],w[1009],vis[1009]; 
    11 bool jud[1009][1009]; 
    12 struct node{
    13     int to,next;
    14 }edge[1000900];
    15 
    16 void add(int x,int y)
    17 {
    18     edge[++tot].to=y;
    19     edge[tot].next=head[x];
    20     head[x]=tot;
    21 }
    22 
    23 void topo()
    24 {
    25     queue<pair<int,int> >q;
    26     for(int i=1;i<=n;i++)
    27         if(!du[i]) q.push(make_pair(i,1));
    28     while(!q.empty())
    29     {
    30         int u=q.front().first;
    31         int val=q.front().second;q.pop();
    32         for(int i=head[u];i;i=edge[i].next)
    33         {
    34             int v=edge[i].to;
    35             if(--du[v]==0) q.push(make_pair(v,val+1));
    36             ans=max(ans,val+1);
    37         }
    38     }
    39 }
    40 
    41 int main()
    42 {
    43     scanf("%d%d",&n,&m);
    44     for(int p=1;p<=m;p++)
    45     {
    46         memset(vis,0,sizeof(vis));
    47         memset(w,0,sizeof(w));
    48         int opt=0;
    49         scanf("%d",&opt);
    50         for(int i=1;i<=opt;i++)
    51             scanf("%d",&w[i]),vis[w[i]]=1;
    52         for(int i=w[1];i<=w[opt];i++)
    53         {
    54             if(!vis[i])
    55                 for(int j=1;j<=opt;j++)
    56                     if(!jud[i][w[j]]) add(i,w[j]),du[w[j]]++,jud[i][w[j]]=1;
    57         }
    58     }
    59 /*    for(int i=1;i<=n;i++)
    60         for(int j=1;j<=n;j++)
    61             printf("%d %d :=%d
    ",i,j,jud[i][j]);
    62         return 0;
    63 */    topo();
    64     printf("%d",ans);
    65     return 0;
    66 }
    67 //判断边有没有连重 
    View Code
  • 相关阅读:
    python 打印出水仙花数
    pycharm 2020 激活码 破解教程
    Python 封装一个函数,查找文字字符串数字英文下标
    Python 分解质因数
    python 封装一个取符串长度的函数
    Python 正整数相加其余忽略
    Python 输入字符串找(String)下标 没有返回-1
    CPU 和 GPU 的区别
    Deferred Shading,延迟渲染(提高渲染效率,减少多余光照计算)【转】
    BumpMap、NormalMap的区别
  • 原文地址:https://www.cnblogs.com/nopartyfoucaodong/p/9553222.html
Copyright © 2011-2022 走看看