zoukankan      html  css  js  c++  java
  • 【洛谷习题】在农场万圣节

    题目链接:https://www.luogu.org/problemnew/show/P2921


    这道题在洛谷上显示的难度(提高+/省选-)对于我来说还真不小。但事实上,思路还是很容易有的。因为每个结点入度为零,所以只有两种情况:环和环上加链(和信息传递那道题很像https://www.cnblogs.com/Mr94Kevin/p/9521585.html)。只要一个点在环上,那么答案就是环的长度;如果是在链上,那么答案就是点到环的距离加上环的长度。同样,参照信息传递那道题的做法,我们可以先删链,再搜环。总之一定要找对判断环的方法,不能错误的认为链环上的点只要入度不为1就是链和环的交点,更不能因此浪费大量时间!!!

     1 #include<cstdio>
     2 
     3 inline int get_num() {
     4     int num = 0;
     5     char c = getchar();
     6     while (c < '0' || c > '9') c = getchar();
     7     while (c >= '0' && c <= '9')
     8         num = num * 10 + c - '0', c = getchar();
     9     return num;
    10 }
    11 
    12 void put_num(int i) {
    13     if (i > 9) put_num(i / 10);
    14     putchar(i % 10 + '0');
    15 }
    16 
    17 const int maxn = 1e5 + 5;
    18 
    19 int n, next[maxn], vis[maxn], d[maxn], ans[maxn], cnt;
    20 
    21 int dfs1(int i) {
    22     int j = next[i];
    23     if (vis[j]) return ans[i] = cnt + 1 - vis[j];
    24     else {
    25         vis[j] = ++cnt;
    26         return ans[i] = dfs1(j);
    27     }
    28 }
    29 
    30 int dfs2(int i) {
    31     if (ans[i]) return ans[i];
    32     int j = next[i];
    33     return ans[i] = dfs2(j) + 1;
    34 }
    35 
    36 int main() {
    37     n = get_num();
    38     for (int i = 1; i <= n; ++i) next[i] = get_num(), ++d[next[i]];
    39     for (int i = 1; i <= n; ++i)
    40         if (!d[i]) {
    41             d[i] = -1;
    42             for (int j = next[i]; ; j = next[j]) {
    43                 if (--d[j]) break;
    44                 else d[j] = -1;
    45             }
    46         }
    47     for (int i = 1; i <= n; ++i)
    48         if (!vis[i] && d[i] != -1) {
    49             cnt = 1;
    50             dfs1(i);
    51         }
    52     for (int i = 1; i <= n; ++i)
    53         if (!vis[i]) dfs2(i);
    54     for (int i = 1; i <= n; ++i) {
    55         if (i != 1) putchar('
    ');
    56         put_num(ans[i]);
    57     }
    58     return 0;
    59 }
    AC代码

    同样的,和信息传递那道题一样,我们也可以不删除链,而是直接遍历,通过加设变量来判断遇到已遍历的点是否是在本次遍历。

     1 #include <cstdio>
     2 
     3 inline int get_num() {
     4     int num = 0;
     5     char c = getchar();
     6     while (c < '0' || c > '9') c = getchar();
     7     while (c >= '0' && c <= '9')
     8         num = num * 10 + c - '0', c = getchar();
     9     return num;
    10 }
    11 
    12 const int maxn = 1e5 + 5;
    13 
    14 int next[maxn], vis[maxn], cnt[maxn];
    15 
    16 int dfs(int i) {
    17     if (cnt[i]) return cnt[i];
    18     else return cnt[i] = dfs(next[i]) + 1;
    19 }
    20 
    21 int main() {
    22     int n = get_num(), dfn = 0, start = 0;
    23     for (int i = 1; i <= n; ++i)
    24         next[i] = get_num();
    25     for (int i = 1; i <= n; ++i)
    26         if (!vis[i]) {
    27             start = dfn + 1;
    28             for (int p = i; p; p = next[p]) {
    29                 ++dfn;
    30                 if (vis[p]) {
    31                     if (vis[p] >= start) {
    32                         int size = dfn - vis[p];
    33                         for (int j = next[p]; ; j = next[j]) {
    34                             cnt[j] = size;
    35                             if (j == p) break;
    36                         }
    37                     }
    38                     break;
    39                 } else vis[p] = dfn;
    40             }
    41         }
    42     for (int i = 1; i <= n; ++i)
    43         if (!cnt[i]) dfs(i);
    44     for (int i = 1; i <= n; ++i)
    45         printf("%d
    ", cnt[i]);
    46     return 0;
    47 }
    AC代码
  • 相关阅读:
    关系型数据库与非关系型数据库
    项目技术点总结
    小程序项目开发总结
    小程序的生命周期
    ES6中的class 与prototype
    js中的深拷贝与浅拷贝
    DOM的构建与优化
    ES6中promise总结
    react服务端渲染
    vue服务端渲染
  • 原文地址:https://www.cnblogs.com/Mr94Kevin/p/9532810.html
Copyright © 2011-2022 走看看