2019 西安邀请赛 M

复制代码
Problem Description
There are n planets in the MOT galaxy, and each planet has a unique number from 1∼n. Each planet is connected to other planets through some transmission channels. There are m transmission channels in the galaxy. Each transmission channel connects two different planets, and each transmission channel has a length.
The residents of the galaxy complete the interplanetary voyage by spaceship. Each spaceship has a level. The spacecraft can be upgraded several times. It can only be upgraded 1 level each time, and the cost is c. Each upgrade will increase the transmission distance by d and the number of transmissions channels by e to the spacecraft. The spacecraft can only pass through channels that are shorter than or equal to its transmission distance. If the number of transmissions is exhausted, the spacecraft can no longer be used.
Alice initially has a 0-level spacecraft with transmission distance of 0 and transmission number of 0. Alice wants to know how much it costs at least, in order to transfer from planet 1 to planet n.

Input
Each test file contains a single test case. In each test file:
The first line contains n, m, indicating the number of plants and the number of transmission channels.
The second line contains c, d, e, representing the cost, the increased transmission distance, and the increased number of transmissions channels of each upgrade, respectively.
Next m lines, each line contains u,v,w, meaning that there is a transmission channel between u and v with a length of w.(2≤n≤105, n-1≤m≤105,1≤u,v≤n ,1≤c,d,e,w≤105)
(The graph has no self-loop , no repeated edges , and is connected)

Output
Output a line for the minimum cost. Output -1 if she can’t reach.

Sample Input
5 7
1 1 1
1 2 1
1 3 5
1 4 1
2 3 2
2 4 5
3 4 3
3 5 5

Sample Output
5

题意
有n个点,编号从1到n,有m条边,每条边有一个长度w。
Alice有一艘飞船,Alice可以给它升级很多次(无限),每升级一次需要花费c,升级一次之后飞船单次可飞行距离增加d,可飞行次数增加e。如果飞船需要飞过一条边,就需要满足单次可飞行距离≥这条路的长度同时可飞行次数不为0。
现在Alice在编号为1的点,她的飞船为0级,单次可飞行距离和可飞行次数都为0,请你求出最小的花费使得Alice可以到达n点,如果不能到达n则输出-1
复制代码

 

 

复制代码
   // 二分更新次数
   //无环无向图且联通 ,就是树 
    #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <cstring>
    using namespace std;
    #define ll long long 
    #define P pair<ll,ll>
    #define N 100100
    #define inf 1e12
    int n,m,cnt;
    ll c,d,E;ll u,v,w;
    ll head[N*2];
    ll dis[N],num[N];
    struct Node{
        ll u,v,w,nex;
        Node(){
        }
        Node(ll u,ll v,ll w,ll nex):u(u),v(v),w(w),nex(nex){}
    }e[N*2];
    void init()
    {
        cnt = 0;
        memset(head,-1,sizeof(head));
    }
    void add(ll u,ll v,ll w)
    {
        e[cnt].u=u;e[cnt].v=v;e[cnt].w=w;
        e[cnt].nex = head[u];head[u]=cnt++;
    }
    bool check(ll mid)
    {
        //假设在起点就已经更新了mid次,验证mid是否满足条件 
        priority_queue<P,vector<P>,greater<P> >q;
        fill(dis,dis+n+1,inf);fill(num,num+n+1,inf);
        dis[1]=num[1]=0; 
        q.push(P(0,1));
        while(!q.empty())
        {
            P tmp =q.top();q.pop();
            ll u=tmp.second;
            if(dis[u]<tmp.first) continue;
            for(ll  i=head[u];i!=-1;i=e[i].nex){
                ll v=e[i].v;
                if(dis[v]>dis[u]+e[i].w&&e[i].w<=mid*d){
                    dis[v] = dis[u] +e[i].w;
                    num[v] = min(num[v],num[u]+1);//更新出最小的 
                    q.push(P(dis[v],v));
                }
            }
        }
        return num[n]<=mid*E;//1: 可以走到n 2 :走过的路径数目满足条件 
    }
    int main()
    {
        init();
        scanf("%d%d",&n,&m);
        scanf("%lld%lld%lld",&c,&d,&E);
        for(int i =0;i<m;i++) {
            scanf("%lld%lld%lld",&u,&v,&w);
            add(u,v,w);add(v,u,w);
        }
        ll l =1,r=100000,res,mid;
        while(l<=r)
        {
            mid = (l+r)>>1;
            if(check(mid)) {    
                res = mid;r=mid-1;
            }
            else{
                l=mid+1;
            }
        }
        printf("%lld\n",res*c);
        return 0;
    }
复制代码

 

 

复制代码
    //code2
       #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <cstring>
    using namespace std;
    #define ll long long 
    #define P pair<ll,ll>
    #define N 100100
    #define inf 1e12
    int n,m,cnt;
    ll c,d,E;ll u,v,w;
    ll head[N*2];
    bool vis[N]; 
    struct Node{
        ll u,v,w,nex;
        Node(){
        }
        Node(ll u,ll v,ll w,ll nex):u(u),v(v),w(w),nex(nex){}
    }e[N*2];
    void init()
    {
        cnt = 0;
        memset(head,-1,sizeof(head));
    }
    void add(ll u,ll v,ll w)
    {
        e[cnt].u=u;e[cnt].v=v;e[cnt].w=w;
        e[cnt].nex = head[u];head[u]=cnt++;
    }
    bool check(ll mid) 
    {
        /*
        由于是树,那么任意两点的路径唯一
        只需要判断在 当前的次数下,在满足单次可飞行距离≥这条路的长度下,凭借的当前可用步数能走到n吗 
        */ 
        memset(vis,0,sizeof(vis));//每次都是重新来 
        ll num =mid*E;ll dd = mid*d;
        //假设在起点就已经更新了mid次,验证mid是否满足条件 
        queue<P>q ;
        q.push(P(1,num)); //first :当前 到达的点 second :还余下的可走的步数 
        vis[1]=1;
        while(!q.empty())
        {
            P tmp =q.front();q.pop();
            ll u = tmp.first;ll cnt=tmp.second;
            if(u==n) return 1;
            else{
                for(ll i=head[u];i!=-1;i=e[i].nex){
                    ll v=e[i].v;
                    if(!vis[v]&&e[i].w<=dd&&cnt>0){
                        vis[v] = 1;
                        q.push(P(v,cnt-1));
                    }
                }
            }
        }
        return 0;
    }
    int main()
    {
        init();
        scanf("%d%d",&n,&m);
        scanf("%lld%lld%lld",&c,&d,&E);
        for(int i =0;i<m;i++) {
            scanf("%lld%lld%lld",&u,&v,&w);
            add(u,v,w);add(v,u,w);
        }
        ll l =1,r=100000,res,mid;
        while(l<=r)
        {
            mid = (l+r)>>1;
            if(check(mid)) {    
                res = mid;r=mid-1;
            }
            else{
                l=mid+1;
            }
        }
        printf("%lld\n",res*c);
        return 0;
    }
复制代码

 

posted on   cltt  阅读(215)  评论(0编辑  收藏  举报

编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
历史上的今天:
2018-07-30 变量
2018-07-30 hiho 1050 树的直径
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示