#include <bits/stdc++.h>
using namespace std;
struct node{
int p;
double g;
double f;
bool operator < (const node &b) const{
if(f==b.f)
return g>b.g;
return f>b.f;
}
};
struct Edge{
int to;
int next;
double w;
};
int n,m;
double max_s;
int ans;
int cnt1,cnt2;
Edge edge1[200005],edge2[200005];
int head1[5005],head2[5005];//1正2反
double h[5005];
inline int read(){
int k=1;
int sum=0;
char c=getchar();
for(;'0'>c || c>'9' ;c=getchar())
if(c=='-') k=-1;
for(;'0'<=c && c<='9';c=getchar())
sum=sum*10+c-'0';
return sum*k;
}
inline void write(int x){
if(x<0) { putchar('-'); x*=-1; }
if(x>9) write(x/10);
putchar(x%10+'0');
}
inline void add(int x,int y,double z,
int &cnt,Edge *edge,int *head){
++cnt;
edge[cnt].to=y;
edge[cnt].next=head[x];
edge[cnt].w=z;
head[x]=cnt;
}
inline void spfa(int p,int *head,Edge *edge){
bool vis[5005]={0};
memset(h,0x7f,sizeof(h));
queue<int>q;
h[p]=0;
vis[p]=1;
q.push(p);
for(int t=1;t;){
p=q.front(); q.pop(); --t; vis[p]=0;
for(int i=head[p];i;i=edge[i].next)
if(edge[i].w+h[p]<h[edge[i].to])
{
int y=edge[i].to;
h[y]=h[p]+edge[i].w;
if(!vis[y])
{
vis[y]=1;
q.push(y);
++t;
}
}
}
}
inline void A_star(int *head,Edge *edge){
double tot=0;
priority_queue<node>q;
q.push((node){1,0,h[1]});
for(int t=1;t;){
node pp=q.top(); q.pop(); --t;
int p=pp.p;
if(p==n){//此处不可放在下面循环里
tot+=pp.g;
if(tot>max_s) return ;
++ans;
}
for(int i=head[p];i;i=edge[i].next)
{
int y=edge[i].to;
double g=pp.g+edge[i].w;;
++t;
q.push((node){y,g,g+h[y]});
}
}
}
int main(){
n=read();
m=read();
scanf("%lf",&max_s);
for(int i=1;i<=m;++i){
int x=read(),y=read();
double z;
scanf("%lf",&z);
add(x,y,z,cnt1,edge1,head1);//正向
add(y,x,z,cnt2,edge2,head2);//反向
}
spfa(n,head2,edge2);
A_star(head1,edge1);
write(ans);
return 0;
}
K短路
题目:codevs 1835
输入样例:
4 6 14.9
1 2 1.5
2 1 1.5
1 3 3
2 3 1.5
3 4 1.5
1 4 1.5
输出样例#1:
3
说明:
有意义的转换方式共4种:
1->4,消耗能量 1.5
1->2->1->4,消耗能量 4.5
1->3->4,消耗能量 4.5
1->2->3->4,消耗能量 4.5
显然最多只能完成其中的3种转换方式(选第一种方式,后三种方式仍选两个),即最多可以转换3份样本。 如果将 E=14.9 改为 E=15,则可以完成以上全部方式,答案变为 4。