您的位置:首页 > 其它

【图论最短路】【CQBZOJ 2431】Trick

2016-11-12 16:08 176 查看
问题 D(2431): Trick

时间限制: 1 Sec 内存限制: 128 MB

题目描述

暴躁的稻草人,最终以自爆来给我们的队伍致命一击,全队血量见底,稻草人也一分为二。还好我们有雨柔妹子,瞬间精力回满。不过事后姜小弟和龙腹黑就开始了报复。他们读取存档,将若干暴躁的稻草人活捉。然后将它们放到一个迷宫的入口。迷宫是有向图。此刻暴躁的稻草人们在1号位置,而迷宫出口在n号位置。因为稻草人会自爆,所以他每经过一条路数量就会加倍。每条路上有敌人,会消耗稻草人c[i](c[i]为负值)当然有些时候路上也会遇到止血草之类的东西,这时候就可以补充一些稻草人咯(c[i]为正值)。如果小稻草人死光了,那么稻草人也就可以看做是挂了。希望你帮助稻姜龙二人算出用最少的初始稻草人使其能够走出迷宫。

输入

第一行两个数N(≤ 50000),M(≤ 100000)表示点位数与边数。

以下M行,每行三个数a,b,c表示从a到b两点间的边权是c(|c| ≤ 10000)

输出

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

样例输入

5 4

1 2 -3

1 3 -6

3 4 1

4 5 -9

样例输出

4

我们可以转换一下思路,不防假设最后只有一个稻草人到了终点,然后按照他的规则反着走回去,便可以求起点的稻草人数量,当然有些时候一个稻草人是走不回去的,当我们进行向回走操作时,若稻草人数量小于1,则把他变成1,继续走。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;

#define MAXN 50000
#define MAXM 100000
#define INF 0x3f3f3f3f
typedef long long int LL;

struct node
{
int v,w;
node *next;
}*adj[MAXN+10],Edges[MAXM+10],*New=Edges;

void addedge(int u,int v,int w)
{
node *p=++New;
p->v=v;
p->w=w;
p->next=adj[u];
adj[u]=p;
}

int N,M;
LL dist[MAXN+10];
bool vis[MAXN+10];
queue<int>que;
LL Spfa(int S,int T)
{
memset(dist,0x3f,sizeof(dist));
memset(vis,0,sizeof(vis));
while(!que.empty())que.pop();

dist[S]=1;
vis[S]=1;
que.push(S);

int now;
while(!que.empty())
{
now=que.front();que.pop();
vis[now]=0;

for(node *p=adj[now];p!=NULL;p=p->next)
if(dist[p->v]>max((dist[now]-p->w+1)/2,1ll))
{
dist[p->v]=max((dist[now]-p->w+1)/2,1ll);
if(!vis[p->v])
{
que.push(p->v);
vis[p->v]=1;
}
}
}

return dist[T];
}

int main()
{
scanf("%d%d",&N,&M);
int i,j;
int a,b,c;

for(i=1;i<=M;++i)
{
scanf("%d%d%d",&a,&b,&c);
addedge(b,a,c);
}

printf("%lld\n",Spfa(N,1));
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  图论 最短路