首页 > 其他分享 >G. Bicycles

G. Bicycles

时间:2024-01-16 14:45:30浏览次数:24  
标签:city 系数 ll Bicycles 终点 速度 speed

原题链接

题记,一道思考加编写加优化耗时2h的题

1.核心:抵达终点的路途中,如果换自行车,一定是换一辆速度系数更小的车
2.从速度系数最小的城市出发,到达终点的cost等于其系数乘上到达终点的最小距离
3.从速度系数第二小的城市出发,到达终点的最小值一定是直接往终点走先去速度系数最小的城市之后再往终点走中的最小值
4.以此类推即可,细节我放在了code里,最细节的一点是这并不是一个多源最短路,而是单源最短路,在每个点作dijk的耗时比整体作spfa快很多

code

#include<bits/stdc++.h>
#define ll long long
using namespace std;

struct edge
{
    ll to;
    ll len;
};
vector<edge> G[1005];
void add(ll x,ll y,ll w)
{
    G[x].push_back({y,w});
    G[y].push_back({x,w});
}//以上操作为存边

struct unit
{
    ll speed;//这个城市自行车的速度系数
    ll id;
    ll cons;
}city[1005];
ll dis[1005];//代表某个点到剩下其余点的最小值
bool cmp(unit a,unit b){return a.speed<b.speed;}
struct fresh
{
    ll to;
    ll val;
    bool operator <(const fresh &b) const{return b.val<val;}//由于二元且升序,所以需要重载运算符
};

void dijk(ll who)//单源最短路
{
    memset(dis,0x3f3f3f,sizeof dis);
    priority_queue<fresh> q;
    q.push({who,0});
    while(q.size())
    {
        ll now=q.top().to;
        ll val=q.top().val;
        q.pop();
        if(dis[now]<=val)continue;
        dis[now]=val;
        for(int i=0;i<G[now].size();i++)
        {
            ll next=G[now][i].to;
            ll v=G[now][i].len+val;
            if(v<dis[next])  q.push({next,v});
        }
    }
}
int main()
{
    ios::sync_with_stdio(0);cin.tie(0);
    ll t;
    cin>>t;
    while(t--)
    {
        ll n,m;
        cin>>n>>m;
        for(int i=1;i<=n;i++)G[i].clear();
        for(ll i=1;i<=m;i++)
        {
            ll x,y,w;
            cin>>x>>y>>w;
            add(x,y,w);
        }

        for(ll i=1;i<=n;i++)
        {
            cin>>city[i].speed;
            city[i].id=i;
        }
        sort(city+1,city+n,cmp);//按速度排序,速度快的在前面,也就是速度系数小的在前面
        dijk(city[1].id);
        city[1].cons=city[1].speed*dis[n];
        ll ans=city[1].cons;//如果没有进入循环代表只有两个值,直接走就行了
        for(ll i=2;i<n;i++)
        {
            dijk(city[i].id);//由于我只需要知道现在这个点到其他点的最小值,并不需要知道所有点之间的距离,我所需要的也只是其他点出发到达n点的最小值
            city[i].cons=city[i].speed*dis[n];//代表直接走
            for(ll j=1;j<i;j++) city[i].cons=min(city[i].cons,city[i].speed*dis[city[j].id]+city[j].cons);//换自行车一定是换一辆速度比自己快的自行车
            if(city[i].id==1) ans=city[i].cons;
        }
        cout<<ans<<endl;
    }
    return 0;
}

标签:city,系数,ll,Bicycles,终点,速度,speed
From: https://www.cnblogs.com/pure4knowledge/p/17967610

相关文章

  • G. Bicycles 分层图单源最短路
    题目链接简单描述一下题意:给定n个点,m条带权无向边,每个点i有一辆速度系数为Si的自行车。每经过一个点即可拥有该点的自行车,在任意两点之间路过的消耗为:已经拥有的某辆自行车的速度Si*边权Wi,求从1号点到n号点的最小消耗。思路:因为需要求的是最小的总消耗,所以在某个点出发时,我......
  • G. Bicycles
    G.BicyclesAllofSlavic'sfriendsareplanningtotravelfromtheplacewheretheylivetoapartyusingtheirbikes.AndtheyallhaveabikeexceptSlavic.Thereare$n$citiesthroughwhichtheycantravel.Theyallliveinthecity$1$andwant......