• 【NOIP2013】车站分级


    虽然这是道普及组的题,但解决的过程还真是挺曲折的。。。QwQ

    本题在洛谷上的链接:https://www.luogu.org/problemnew/show/P1983


    也捣鼓了很久的图论了(其实并没有多久),打算把这道题作为一个分界点,转去学一会DP。没想到,看完题目,我的第一反应并不是图论知识。

    最初的思路是这样,对于每个站点,先设置级别为1,然后对于读入的每趟列车,因为读入的车站级别一定比没读入的高,就检查每个车站,不合格就修改。结果只有20分,仔细一想确实不对。对于每趟列车,读入车站的级别应当保证一直比未读入的高,然而这种只考虑本趟列车的做法,显然可能会与之前的产生冲突。

    然后就开始考虑图论怎么做,比较容易想到的是将大小关系用边来表示,然后跑拓扑排序(其实一开始就想到了),令人不安的是建图过程,复杂度极高!没办法,还是硬着头皮写吧。但是只有60分,提示是运行时错误,那肯定数组开小了。最多有1000个点,又因为是有向图且不会出现两个点之间有两条边的情况,所以边数不会超过1000*(1000-1)/2。把数组稍稍调大一点,咦,怎么成了70分。

    看题解。。。哦!原来在读入边的过程中,因为是用邻接链表存边,每条边可能被读入多次!所以需要加一个标志数组,或者是使用邻接矩阵存边。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <queue>
     4 
     5 using namespace std;
     6 
     7 inline int get_num() {
     8     int num = 0;
     9     char c = getchar();
    10     while (c < '0' || c > '9') c = getchar();
    11     while (c >= '0' && c <= '9')
    12         num = num * 10 + c - '0', c = getchar();
    13     return num;
    14 }
    15 
    16 const int maxn = 1005;
    17 
    18 int graph[maxn][maxn], ind[maxn], stop[maxn], vis[maxn], level[maxn];
    19 
    20 queue<int> q;
    21 
    22 int main() {
    23     int n = get_num(), m = get_num(), ans = 0;
    24     for (int i = 1; i <= m; ++i) {
    25         int s = 0, t = 0, cnt = get_num();
    26         memset(stop, 0, sizeof(stop));
    27         memset(vis, 0, sizeof(vis));
    28         for (int j = 1; j <= cnt; ++j) {
    29             if (j == 1) vis[s = stop[j] = get_num()] = 1;
    30             else if (j == cnt) vis[t = stop[j] = get_num()] = 1;
    31             else vis[stop[j] = get_num()] = 1;
    32         }
    33         for (int j = 1; j <= cnt; ++j) {
    34             for (int k = s; k <= t; ++k)
    35                 if (!vis[k] && !graph[k][stop[j]])
    36                     graph[k][stop[j]] = 1, ++ind[stop[j]];
    37         }
    38     }
    39     for (int i = 1; i <= n; ++i)
    40         if (!ind[i]) {
    41             level[i] = 1;
    42             q.push(i);
    43         }
    44     while (!q.empty()) {
    45         int u = q.front();
    46         q.pop();
    47         for (int v = 1; v <= n; ++v)
    48             if (graph[u][v]) {
    49                 if (level[v] < level[u] + 1)
    50                     level[v] = level[u] + 1;
    51                 if (!(--ind[v])) q.push(v);
    52             }
    53         if (ans < level[u]) ans = level[u];
    54     }
    55     printf("%d", ans);
    56     return 0;
    57 }
    AC代码(邻接矩阵)
  • 相关阅读:
    自测项目:批量删除云盘重复文件
    表格更新成本 二 问用户年龄和口令,直到他们提供有效的输入
    知乎抓取、写入文档
    倒打印心
    HDU 1102 Constructing Roads
    C++模板:字典树
    HDU 3015 Disharmony Trees
    HDU 2227 Find the nondecreasing subsequences
    HDU 3486 Interviewe
    C++模板:ST算法
  • 原文地址:https://www.cnblogs.com/Mr94Kevin/p/9588110.html
Copyright © 2020-2023  润新知