Description
iPig在假期来到了传说中的魔法猪学院,开始为期两个月的魔法猪训练。经过了一周理论知识和一周基本魔法的学习之后,iPig对猪世界的世界本原有了很多的了解:众所周知,世界是由元素构成的;元素与元素之间可以互相转换;能量守恒……。 能量守恒……iPig 今天就在进行一个麻烦的测验。iPig 在之前的学习中已经知道了很多种元素,并学会了可以转化这些元素的魔法,每种魔法需要消耗 iPig 一定的能量。作为 PKU 的顶尖学猪,让 iPig 用最少的能量完成从一种元素转换到另一种元素……等等,iPig 的魔法导猪可没这么笨!这一次,他给 iPig 带来了很多 1 号元素的样本,要求 iPig 使用学习过的魔法将它们一个个转化为 N 号元素,为了增加难度,要求每份样本的转换过程都不相同。这个看似困难的任务实际上对 iPig 并没有挑战性,因为,他有坚实的后盾……现在的你呀! 注意,两个元素之间的转化可能有多种魔法,转化是单向的。转化的过程中,可以转化到一个元素(包括开始元素)多次,但是一但转化到目标元素,则一份样本的转化过程结束。iPig 的总能量是有限的,所以最多能够转换的样本数一定是一个有限数。具体请参看样例。
占总分不小于 10% 的数据满足 N <= 6,M<=15。
占总分不小于 20% 的数据满足 N <= 100,M<=300,E<=100且E和所有的ei均为整数(可以直接作为整型数字读入)。
所有数据满足 2 <= N <= 5000,1 <= M <= 200000,1<=E<=107,1<=ei<=E,E和所有的ei为实数。
Solution
所有的转化方法可以看成是有向边,实际要求的是一个最大整数k使得第1到第k短路的长度和不大于E
这题十分不友好,洛谷上的数据专门卡A*,bzoj的数据专门卡优先队列空间,一开始又十分naïve打了左偏树,凎
Code
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
#define fill(x,t) memset(x,t,sizeof(x))
const int INF=0x3f3f3f3f;
const int N=50005;
const int E=200005;
struct edge {int x,y; double w; int next;} e[E];
struct data {
int x; double f,g;
bool operator <(data b) const {
return f+g<b.f+b.g;
}
} val[N];
struct HEAP {
data val[E*14]; int tot;
void push(data x) {
val[++tot]=x;
for (int i=tot;i>1&&val[i]<val[i/2];i/=2) {
std:: swap(val[i],val[i/2]);
}
}
data pop() {
data ret=val[1]; val[1]=val[tot]; tot--;
for (int i=1;val[i*2]<val[i]&&i*2<=tot||val[i*2+1]<val[i]&&i*2+1<=tot;) {
if (val[i*2]<val[i*2+1]||i*2+1>tot) {
std:: swap(val[i],val[i*2]);
i*=2;
} else {
std:: swap(val[i],val[i*2+1]);
i=i*2+1;
}
}
return ret;
}
bool empty() {
return tot==0;
}
} heap;
int cnt[N],ls[N],V,edCnt;
int lson[N],rson[N],fa[N];
int queue[N];
double dis[N];
bool vis[N];
void add_edge(int x,int y,double w) {
e[++edCnt]=(edge) {x,y,w,ls[x]}; ls[x]=edCnt;
}
void spfa(int st,int ed) {
int head=1,tail=1; queue[tail]=st;
vis[st]=1;
rep(i,0,N-1) dis[i]=INF; dis[st]=0;
while (head<=tail) {
int now=queue[head++];
for (int i=ls[now];i;i=e[i].next) {
if (dis[now]+e[i].w<dis[e[i].y]) {
dis[e[i].y]=dis[now]+e[i].w;
if (!vis[e[i].y]) {
vis[e[i].y]=1;
queue[++tail]=e[i].y;
}
}
}
vis[now]=0;
}
}
void A_star(int st,int ed,double lim) {
heap.push((data) {st,0,dis[st]});
double tot=0;
while (!heap.empty()) {
data top=heap.pop();
cnt[top.x]++;
if (top.x==ed) {
tot+=top.f;
if (tot>lim) {
printf("%d\n", cnt[top.x]-1);
return ;
}
continue;
}
for (int i=ls[top.x];i;i=e[i].next) {
heap.push((data) {e[i].y,top.f+e[i].w,dis[e[i].y]});
}
}
}
int main(void) {
int n,m; double lim;
scanf("%d%d%lf",&n,&m,&lim);
rep(i,1,m) {
int x,y; double w; scanf("%d%d%lf",&x,&y,&w);
add_edge(y,x,w);
}
spfa(n,1);
fill(ls,0); int tmp=edCnt; edCnt=0;
rep(i,1,tmp) add_edge(e[i].y,e[i].x,e[i].w);
A_star(1,n,lim);
return 0;
}