luogu P4042 [AHOI2014/JSOI2014]骑士游戏
5.17家长会
3点放学
于是和姐出去约会qwq
拿着咖啡在大商无聊的转
姐就给我讲了这道题
本质是个图论题
先把每个点压入队列
初始点到其的距离是魔法攻击的花费
每次弹出一个点,算出用普通攻击杀死它再杀了它所有儿子(即从它尸体蹦出来的怪兽)的费用
如果比原来花费小,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;
}
然后 总的来说5.17过得还不错
遗憾什么的 无视就好了