列表

详情


MT17. 共享单车

描述

给出一张图,图上有 n 个节点,从 1 到 n 编号,和 m 条边,每条边有一个权重,表示小明走路通过这条边的时间,所有边都是无向的。

小明从 1 号节点出发,他要去 n 号节点,他想用的总时间尽可能的短。小明有共享单车 APP ,图上有些节点有共享单车,当他到达一个有车节点后,他就可以一直骑车,如果一条边走路通过的时间是 t ,那么骑车通过的时间就是 t/2 ,这里的除法是向下取整,如 t = 1 时 t/2 = 0,t = 2时,t/2 = 1。
小明可以先走到一个节点取车再骑车过去,也可以直接走过去,问他在最优策略下,需要多少时间从 1 到 n。

数据范围:   

输入描述

第一行两个数 n,m ,接下来有 m 行,每行三个数 u,v,w ,表示 u 和 v 之间有一条边权为 w 的无向边 接下来一个数 k ,表示有 k 个节点有车,最后输入 k 行,表示有车节点的编号 输入的图中可能有自环和重边

输出描述

输出一个数,从 1 到 n 的最少所需的时间,如果 1 和 n 不连通,输出 -1

示例1

输入:

4 3
1 3 1
1 2 3
2 4 4
1
3

输出:

4

说明:

小明走过去拿到车,然后骑车去目的地,路线入图:

原站题解

C++ 解法, 执行用时: 55ms, 内存消耗: 8192KB, 提交时间: 2021-10-17

#include <bits/stdc++.h>
using namespace std;
 
struct Edge{
    int v, w;
};
 
struct P{
    int id;
    long s;
    bool flag;
};
 
struct cmp{
    bool operator()(const P &p1, const P &p2)const{
        return p1.s > p2.s;
    }
};
 
long vis[100003][2];
bool mp[100003] = {false};
 
int main(){
    memset(vis, 0x3f3f, sizeof(vis));
    memset(mp, false, sizeof(mp));
    int n, m, u, v, w, k;
    long t;
    scanf("%d%d", &n, &m);
    vector<Edge> G[n+1];
    for(int i=0;i<m;i++){
        scanf("%d%d%d", &u, &v, &w);
        G[u].push_back({v, w});
        G[v].push_back({u, w});
    }
    scanf("%d", &k);
    while(k--){
        scanf("%d", &u);
        mp[u] = true;
    }
    priority_queue<P, vector<P>, cmp> q;
    q.push({1, 0, mp[1]});
    vis[1][mp[1]] = 0;
    while(!q.empty()){
        P p = q.top();
        q.pop();
        if(p.id == n){
            printf("%ld\n", p.s);
            return 0;
        }
        for(auto &e: G[p.id]){
            if(p.flag)
                t = p.s + e.w/2;
            else
                t = p.s + e.w;
            bool flag = p.flag | mp[e.v];
            if(t < vis[e.v][flag]){
                vis[e.v][flag] = t;
                q.push({e.v, t, flag});
            }
        }
    }
    printf("-1\n");
    return 0;
}

C++14 解法, 执行用时: 60ms, 内存消耗: 9980KB, 提交时间: 2020-07-28

#include<bits/stdc++.h>
using namespace std;
long visit[100005][2];
bool has_bike[100005] = {false};
struct node{
    long val;
    int index;
    bool has_bike;
    /*bool operator<(const node&n)const{
        return val>n.val; // 
    }*/
};
class comparenode{
    public:
        bool operator()(const node& lhs,const node& rhs)const{
            return lhs.val>rhs.val;
        }
};
int main(){
    memset(visit,0x3f3f,sizeof(visit));
    int n,m;
    int u,v,w;
    scanf("%d %d",&n,&m);
    vector<vector<pair<int,int> > > graph(n+1);
    for(int i=0;i<m;i++){
        scanf("%d %d %d",&u,&v,&w);
        graph[u].push_back({v,w});
        graph[v].push_back({u,w});
    }
    int k,id;
    scanf("%d",&k);
    for(int i=0;i<k;i++){
        scanf("%d",&id);
        has_bike[id] = true;
    }
    priority_queue<node,vector<node>,comparenode> q;
    q.push({0,1,has_bike[1]});
    visit[1][has_bike[1]] = 0; //
    while(!q.empty()){
        node head = q.top();
        q.pop();
        if(head.index == n){
            cout<<head.val;
            return 0;
        }
        for(pair<int,int>& nxt:graph[head.index]){
            long tim = head.val + nxt.second;
            if(head.has_bike)
                tim = head.val + (nxt.second>>1);
            if(tim<visit[nxt.first][head.has_bike|has_bike[nxt.first]]){
                visit[nxt.first][head.has_bike|has_bike[nxt.first]] = tim;
                q.push({tim,nxt.first,head.has_bike||has_bike[nxt.first]});
            }
        }
    }
    printf("%d\n",-1);
    return 0;
}

上一题