首页 > Web开发 > 详细

P4042 [AHOI2014/JSOI2014]骑士游戏

时间:2019-05-16 20:34:36      阅读:245      评论:0      收藏:0      [点我收藏+]

前往>>暴风城

第一次写SPFA!(惭愧

对于某个怪兽,杀死它的最小消耗 = min(它的魔法消耗,它的物理消耗 + 杀死它所有儿子的消耗)

可以看出,一个点可能被它的儿子更新,并且可能去更新它的父亲。

考虑用最短路解决这道题,从一个假设的起点0出发,要求它到1的最短距离。1~n每个点的距离初始应为INF。

将每个怪物的消耗更新为它的魔法消耗,并加入队列;

弹出队首,检查它能不能被更新。如果可以,则说明它有可能更新它的父亲,将它的所有父亲加入队列;

直到队列为空为止。

代码如下

技术分享图片
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#define MogeKo qwq
#include<queue>
using namespace std;
const int maxn = 2e6;
int n,r,x;
long long ad[maxn],ap[maxn],dis[maxn];
int head[maxn][2],to[maxn][2],nxt[maxn][2],cnt[2];
bool vis[maxn];
queue <int> q;

void add(int x,int y,int op) {
    to[++cnt[op]][op] = y;
    nxt[cnt[op]][op] = head[x][op];
    head[x][op] = cnt[op];
}

void SPFA() {
    for(int i = 1; i <= n; i++) {
        q.push(i);
        vis[i] = true;
    }
    while(!q.empty()) {
        int u = q.front();
        q.pop();
        vis[u] = false;
        long long tem = ad[u];
        for(int i = head[u][1]; i; i = nxt[i][1])
            tem += dis[to[i][1]];
        if(tem >= dis[u])continue;
        dis[u] = tem;
        for(int i = head[u][0]; i; i = nxt[i][0]) {
            int v = to[i][0];
            if(vis[v])continue;
            q.push(v);
            vis[v] = true;
        }
    }
}


int main() {
    scanf("%d",&n);
    for(int i = 1; i <= n; i++) {
        scanf("%lld%lld%d",&ad[i],&ap[i],&r);
        dis[i] = ap[i];
        for(int j = 1; j <= r; j++) {
            scanf("%d",&x);
            add(x,i,0);
            add(i,x,1);
        }
    }
    SPFA();
    printf("%lld",dis[1]);
    return 0;
}
View Code

P4042 [AHOI2014/JSOI2014]骑士游戏

原文:https://www.cnblogs.com/mogeko/p/10877749.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!