zoukankan      html  css  js  c++  java
  • BZOJ3875: [Ahoi2014&Jsoi2014]骑士游戏

    【传送门:BZOJ3875


    简要题意:

      给出n种怪物,每种怪物都带有三个值,S[i],K[i],R[i],分别表示对他使用普通攻击的花费,使用魔法攻击的花费,对他使用普通攻击后生成的其他怪物。

      每种怪物只能用法术攻击来消灭,用普通攻击只能将怪物变成其他怪物

      当前第一种怪物来了,请问将怪物完全消灭的最小花费


    题解:

      首先一看就像DP,设f[i]为消灭第i种怪物的最小花费,可以列出方程:f[i]=min(K[i],∑f[j](将第i种怪物能生成的怪物消灭的最小花费总和))

      但是这种方法显然会出现环,那么我们就用近似SPFA的方法来解决这个问题

      首先将每种怪物放入队列,然后设d=s[x]+∑f[j],如果d<f[x]的话,就更新f[x]

      但是我们不但要更新f[x],还要更新能够生成第x种怪物的怪物,所以我们就要把这些怪物也放进队列里(如果这些怪物本身就在队列里的话,就不用)

      最后输出f[1]就可以了

      PS:要用STL容器来保存怪物生成怪物的信息(不然会爆空间),而且最好用queue来保存队列


    参考代码:

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    using namespace std;
    typedef long long LL;
    queue<int>q;
    vector<int>c[210000];
    vector<int>cd[210000];
    bool v[210000];
    LL f[210000],s[210000],k[210000];
    int main()
    {
        int n;
        scanf("%d",&n);
        int head=1,tail=1;int r;
        for(int i=1;i<=n;i++)
        {
            scanf("%lld%lld",&s[i],&k[i]);
            f[i]=k[i];
            scanf("%d",&r);
            q.push(i);v[i]=true;
            while(r--)
            {
                int x;
                scanf("%d",&x);
                c[i].push_back(x);
                cd[x].push_back(i);
            }
        }
        while(q.empty()==0)
        {
            int x=q.front();
            LL d=s[x];
            for(int i=0;i<c[x].size();i++) d+=f[c[x][i]];
            if(f[x]>d)
            {
                f[x]=d; 
                for(int i=0;i<cd[x].size();i++)
                {
                    if(v[cd[x][i]]==false)
                    {
                        v[cd[x][i]]=true;
                        q.push(cd[x][i]);
                    }
                }
            }
            q.pop();
            v[x]=false;
        }
        printf("%lld
    ",f[1]);
        return 0;
    }

     

  • 相关阅读:
    了解windows下的npm
    “jupyter notebook 不能导入python库但是终端上可以实现”的问题的解决
    本地创建的jupyter notebook 无法连接本地环境(即不能运行代码)
    win10 + ubuntu 下右键新建md文件(转载)
    LeetCode刷题2
    【入门】离散化
    【10.5NOIP普及模拟】sum
    【10.5NOIP普及模拟】sort
    【2020.02.01NOIP普及模拟4】怪兽
    [图论]最小花费
  • 原文地址:https://www.cnblogs.com/Never-mind/p/7909516.html
Copyright © 2011-2022 走看看