K短路

#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。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值