tyvj 火焰巨魔的惆怅

来源:互联网 发布:ubuntu vim使用 编辑:程序博客网 时间:2024/04/29 07:36

描述 Description

我们把火焰巨魔所处的位置抽象成一张有向图,他的位置就是1号点位,目的就是走到第N号点位,因为小火人会裂嘛,所以我们可以看做每走一条路,小火人的数量都会加倍,而每条路上的敌人有多强,会消耗多少小火人c[i]也会给出(c[i]为负值);当然有些时候路上也会遇到魔法泉之类的东西,这时候就可以补充一些小火人咯(c[i]为正值)。如果小火人死光了,那么火焰巨魔也就可以看做是挂了,毕竟智力型英雄就是脆啊。希望你帮助火焰巨魔用最少的初始小火人逃离这次屠杀。

输入格式 InputFormat

第一行两个数N(<=50000),M(<=100000)表示点位数与边数。
一下M行,每行三个数a,b,c表示a,b两点间的边权是c(|c|<=10000)

输出格式 OutputFormat

输出仅一个整数,表示最小初始小火人数。

样例输入 SampleInput 

5 41 2 -31 3 -63 4 14 5 -9

样例输出 SampleOutput 

4

数据范围和注释 Hint

初始小火人为4个,到3点剩2个,到4变成5个,到5剩1个。
所以初始最少为4,更少的小火人是不足以走到5号点位的。

题解

这道题有一点点恶心,不过还好。spfa倒着做,注意当dis[i]<1时,dis[i]=1。
代码如下
#include<cstdio>#include<cstring>#include<cstdlib>#include<iostream>#include<cmath>using namespace std;int n,m,zz=0,head[50002];struct bian{int to,nx,l;} e[200002];int q[50002],dis[50002];bool pd[50002];void insert(int x,int y,int z){zz++; e[zz].to=x; e[zz].l=z; e[zz].nx=head[y]; head[y]=zz;}int calcu(int x){if(x%2!=0) x=x+1;    x=x/2;    return x;}void spfa(){memset(pd,false,sizeof(pd));memset(dis,127/3,sizeof(dis));int t=0,w=1;q[0]=n; pd[n]=true; dis[n]=1;while(t!=w)   {pd[q[t]]=false;int p=q[t],i=head[p]; t=t%n+1; while(i)   {int s=calcu(dis[p]-e[i].l);if(s<dis[e[i].to])       {dis[e[i].to]=s;        if(dis[e[i].to]<1) dis[e[i].to]=1;    if(!pd[e[i].to])   {pd[e[i].to]=true; q[w]=e[i].to; w=w%n+1;}   }i=e[i].nx;   }   }printf("%d\n",dis[1]);}int main(){scanf("%d%d",&n,&m);for(int i=1;i<=m;i++)   {int x,y,z;    scanf("%d%d%d",&x,&y,&z);    insert(x,y,z);   }spfa();return 0;}


0 0
原创粉丝点击