• BZOJ3875 AHOI2014/JSOI2014骑士游戏(动态规划)


      容易想到设f[i]为杀死i号怪物所消耗的最小体力值,由后继节点更新。然而这显然是有后效性的,正常的dp没法做。

      虽然spfa已经死了,但确实还是挺有意思的。只需要用spfa来更新dp值就可以了。dij看起来也差不多。

      更新部分写的看起来就很慢很能优化一波,在luogu上T一个点,然而实在太懒了就算了吧(

      记得我们老师说过某位学长省选前几乎什么省选算法都不会,然后当场切掉了这题,然后进了省队,然后拿了cu,最后进了pku。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    using namespace std;
    #define N 200010
    #define ll long long
    #define inf 100000000000000000
    ll read()
    {
        ll x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    int n,q[N];
    ll f[N];
    bool flag[N];
    struct data
    {
        ll x,y;
        vector<int> from,to;
    }a[N];
    int inc(int &x){x++;if (x>n+1) x-=n+1;return x;}
    bool cmp(const int &a,const int&b)
    {
        return f[a]<f[b];
    }
    void spfa()
    {
        int head=0,tail=n;for (int i=1;i<=n;i++) q[i]=i,flag[i]=1,f[i]=a[i].y;
        sort(q+1,q+n+1,cmp);
        do
        {
            int x=q[inc(head)],s=a[x].from.size();flag[x]=0;
            for (int i=0;i<s;i++)
            {
                int y=a[x].from[i];
                int t=a[y].to.size();ll sum=a[y].x;
                for (int j=0;j<t;j++)
                {
                    sum+=f[a[y].to[j]];
                    if (sum>f[y]) break;
                }
                if (sum<f[y])
                {
                    f[y]=sum;
                    if (!flag[y]) q[inc(tail)]=y,flag[y]=1;
                }
            }
        }while (head!=tail);
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj3875.in","r",stdin);
        freopen("bzoj3875.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        n=read();
        for (int i=1;i<=n;i++)
        {
            a[i].x=read(),a[i].y=read();
            int t=read();
            while (t--)
            {
                int x=read();
                a[x].from.push_back(i),
                a[i].to.push_back(x);
            }
        }
        spfa();
        cout<<f[1];
        return 0;
    }
  • 相关阅读:
    看某视频开始做LINUX笔记的第一天
    shell作业01
    学习shell的第一天
    学python的第三天
    【安全】573- 大前端网络安全精简指南手册
    【JS】572- JS 经典实例收集整理
    【Vuejs】571- Vue 虚拟DOM和Diff算法源码解析
    【JS】570- 揭开 JavaScript 引擎的面纱
    【JS】569- 如何避免这4类 JavaScript 内存泄漏?
    【拓展】如何在Gihub上面精准搜索开源项目?
  • 原文地址:https://www.cnblogs.com/Gloid/p/9748982.html
Copyright © 2020-2023  润新知