• [P2921][USACO08DEC]在农场万圣节Trick or Treat on the Farm (记忆化搜索/DP?,Tarjan?)


    第一看还以为是水题

    随便打了一个bfs只有40分……

    然后开始颓废

    #include<bits/stdc++.h>
    #define N 100005
    using namespace std;
    int nxt[N];
    bool vis[N];
    void bfs(int x)
    {
        memset(vis, 0, sizeof(vis));
        queue<int>q;
        q.push(x);
        vis[x] = true;
        int cnt = 1;
        while (!q.empty())
        {
            int now = q.front();
            if (vis[nxt[now]] == true)
            {
                printf("%d
    ", cnt);
                return;
            }
            else {
                q.pop();
                q.push(nxt[now]);
                cnt++;
                vis[nxt[now]] = true;
            }
        }
    }
    int main()
    {
        int n; scanf("%d", &n);
        for (int i = 1; i <= n; i++)
        {
            scanf("%d", &nxt[i]);
        }
        for(int i=1;i<=n;i++)
        bfs(i);
    }
    垃圾代码

    然后在水社区的时候

    看到一个当时和我一起打这道题的网友@Frozencode (貌似是位大佬)提到这道题 

    一开始没怎么想写博客的

    但是现在还是写吧

    思路

    之前是bfs,想用记忆化很难实现(我这个蒟蒻没打出来,大佬见笑了)

    一开始想储存到一个点的需要的步骤储存下来

    但是bfs会一直更新,不能那么草率地使用啊

    然后看tag是DP?我不会DP

    于是颓废的我点开了题解

    题解一个是玄学模拟。我不会模拟

    然后大神们很多写的Tarjan。为了试图看懂大佬的代码,我甚至想去学tarjan。但是我不会tarjan。

    无奈之下,我还是回归开始的搜索,但是打dfs。

    结果过了……

    代码

    献丑了

    VS的码风

    #include<bits/stdc++.h>
    #define N 100005
    using namespace std;
    int n,x,to[N],rd[N],w[N],dep[N],mk[N];
    char vis[N], ins[N];
    int dfs(int x);
    int main()
    {
        scanf("%d", &n);
        for (int i = 1; i <= n; ++i)
            scanf("%d",&to[i]),++rd[to[i]];
        for (int i = 1; i <= n; ++i)
            if (!rd[i]) w[i] = 1, dfs(i);
        for (int i = 1; i <= n; ++i)
            if (!vis[i]) dfs(i);
        for (int i = 1; i <= n; ++i)
            printf("%d
    ",w[i]);
        return 0;
    }
    int dfs(int x)
    {
        int t = to[x]; vis[x] = ins[x] = 1;
        if (!vis[t])
        {
            dep[t] = dep[x] + 1;
            w[x] = dfs(t);
            w[x] += (mk[t] ? (mk[x] = (mk[x] != 2 ? 1 : 0), 0) : 1);
        }
        else
            if (ins[t])
                w[x] = dep[x] - dep[t] + 1, mk[x] = 1, mk[t] = (x == t ? 0 : 2);
            else
                w[x] = w[t] + 1;
        ins[x] = 0;
        return w[x];
    }

    想睡觉了……因此不多解释了

    现在23:11

    思路也大多数是看题解的

    我去找找……

    找到了

    这位大神的https://www.luogu.org/blog/backupnoob/solution-p2921

    虽然压行可读性低,但是基本可以看懂

    (说白了吧,我抄题解的……)

    深深感觉到自己的弱小

  • 相关阅读:
    高性能Javascript 选择器API学习笔记
    Backbone学习笔记二 Events
    递归用函数、存储过程实现的效果
    用触发器实现动态新增列
    局域网自动备份删除
    游标变量用法经典
    如何区分大小写字母、全角半角
    列的分拆显示
    2005的行列转换
    批量分离和附加数据库
  • 原文地址:https://www.cnblogs.com/lincold/p/9863878.html
Copyright © 2020-2023  润新知