HDU 2066

HDU 2066 一个人的旅行

思路 : 题目中没有给出小草家的位置,只给出了与他家相连的城市,我们可以把这三个点,

缩成一个点来看待,本来要从两个源点去找最短路,然后在去求最短路里面的最小值,

这样缩点之后,只用一次dijkstra就好了,因为缩的点,在题目中没有明确给出,我们放到0这个位置上

就会增加一个 点 ,所以总的顶点数目++,注意题目中可能出现重边,只取最小的就好。

#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 233,INF = 0x3f3f3f3f;
int t,s,d,g[N][N],dist[N],n;
bool st[N];
void dij(){
    memset(st,0,sizeof st);
    memset(dist,0x3f,sizeof dist);
    dist[0] = 0;
    n++;
    for(int i = 0;i < n;++i){
        int t = -1;
        for(int j = 0;j < n; ++j){
            if(!st[j] && (t == -1 || dist[j] < dist[t]))
                t = j;
        }
        st[t] = 1;
        for(int j = 0;j < n; ++j){
            dist[j] = min(dist[j],dist[t] + g[t][j]);
        }
    }
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    int a,b,time;
    while(cin >> t >> s >> d){
        memset(g,0x3f,sizeof g);
        n = 0;
        int mini = INF,x;
        for(int i = 0;i < t; ++i){
            cin >> a >> b >> time;
            if(time < g[a][b]) {//处理重边
                g[a][b] = g[b][a] = time;
            }
            n = max(max(a,b),n);//求最大的顶点数目
        }
        for(int i = 0;i < s; ++i){
            cin >> x;
            g[0][x] = g[x][0] = 0;//缩点
        }
        dij();
        for(int i = 0;i < d; ++i){
            cin >> x;//求最短路中,花费时间最小的
            mini = min(mini,dist[x]);
        }
        cout << mini << endl;
    }
    return 0;
}
posted @ 2019-09-09 00:02  lukelmouse  阅读(110)  评论(0编辑  收藏  举报