luogu P4042 [AHOI2014/JSOI2014]骑士游戏

5.17家长会

3点放学 

于是和姐出去约会qwq

拿着咖啡在大商无聊的转

姐就给我讲了这道题

某死宅发现一款游戏的故事emmmm

本质是个图论题

先把每个点压入队列

初始点到其的距离是魔法攻击的花费

每次弹出一个点,算出用普通攻击杀死它再杀了它所有儿子(即从它尸体蹦出来的怪兽)的费用

如果比原来花费小,dis就改一下

然后它的所有父亲自然也可以被更新,就把它的父亲压入队列

操作到队列为空

就好了w

#include<cstdio>
#include<queue>
#define sev en
using namespace std;
#define N 2000010

long long atk[N],dis[N];
int nxt[N][2],to[N][2],head[N][2],cnt[2];
int vis[N],n;
queue<int>q;

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

void spfa(){
    for(int i = 1;i <= n;i++){
    q.push(i);
    vis[i] = 1;
    }
    while(!q.empty()){
    int x = q.front();
    q.pop();
    vis[x] = 0;
    long long tmp = atk[x];
    for(int i = head[x][1];i;i = nxt[i][1])
        tmp += dis[to[i][1]];
    if(tmp >= dis[x])
        continue;
    dis[x] = tmp;
    for(int i = head[x][0];i;i = nxt[i][0]){
        int v = to[i][0];
        if(!vis[v]){
        q.push(v);
        vis[v] = 1;
        }
    }
    }
}

int main(){
    //   int n;
    scanf("%d",&n);
    for(int i = 1;i <= n;i++){
    int num;
    scanf("%lld%lld%d",&atk[i],&dis[i],&num);
    for(int j = 1;j <= num;j++){
        int x;
        scanf("%d",&x);
        add(x,i,0);
        add(i,x,1);
    }
    }
    spfa();
    printf("%lld",dis[1]);
    return 0;
}
我也想宅着玩游戏qaq

然后 总的来说5.17过得还不错

遗憾什么的 无视就好了

 

posted @ 2019-05-19 17:45  ./seven  阅读(140)  评论(1编辑  收藏  举报