码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 2680 Choose the best route (Dijkstra & 反向图)

时间:2015-01-20 12:04:28      阅读:153      评论:0      收藏:0      [点我收藏+]

标签:

Choose the best route

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7764    Accepted Submission(s): 2581


Problem Description
One day , Kiki wants to visit one of her friends. As she is liable to carsickness , she wants to arrive at her friend’s home as soon as possible . Now give you a map of the city’s traffic route, and the stations which are near Kiki’s home so that she can take. You may suppose Kiki can change the bus at any station. Please find out the least time Kiki needs to spend. To make it easy, if the city have n bus stations ,the stations will been expressed as an integer 1,2,3…n.
 

Input
There are several test cases. 
Each case begins with three integers n, m and s,(n<1000,m<20000,1=<s<=n) n stands for the number of bus stations in this city and m stands for the number of directed ways between bus stations .(Maybe there are several ways between two bus stations .) s stands for the bus station that near Kiki’s friend’s home.
Then follow m lines ,each line contains three integers p , q , t (0<t<=1000). means from station p to station q there is a way and it will costs t minutes .
Then a line with an integer w(0<w<n), means the number of stations Kiki can take at the beginning. Then follows w integers stands for these stations.
 

Output
The output contains one line for each data set : the least time Kiki needs to spend ,if it’s impossible to find such a route ,just output “-1”.
 

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

Sample Output
1 -1
 

Author
dandelion
 

Source




题意:一个人,要坐公交去上班。一直有n各站点,m条路线,已知他可以从w各站点出发坐车,求到达目的地s所用的最少时间。如不能到达,则输出-1。


解析:Dijkstra算法,不过直接使用w次Dijkstra,会超时的。下面有两个思路:

1.将这个人的位置设为站点0,然后将站点0和那w个出发点连接在一起,相当于从他家到这些站点的时间为0。然后再使用Dijkstra,输出d[s]即可。

2.利用反向图,因为可以有多个起点,但是只有一个终点,所以反向图的话,相当于只有一个起点,好多个终点了,这样只要使用一次Dijkstra,然后输出w个起点中的最小值即可。

PS:一定要注意公交线路是单向的,一定要建成有向图!!!



AC代码:


思路一

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
#define INF 1e7 + 2
const int maxn = 1000 + 5;

int n, m;
int w[maxn][maxn], d[maxn], v[maxn];

void dijkstra(int s){
    memset(v, 0, sizeof(v));
    for(int i=0; i<=n; i++) d[i] = w[s][i];
    d[s] = 0;
    v[s] = 1;
    for(int i=0; i<=n; i++){
        int x, m = INF;
        for(int y=0; y<=n; y++)
            if(!v[y] && d[y] <= m) m = d[x = y];
        if(m == INF) break;
        v[x] = 1;
        for(int y=0; y<=n; y++) d[y] = min(d[y], d[x] + w[x][y]);
    }
}

int main(){
    #ifdef sxk
        freopen("in.txt", "r", stdin);
    #endif //sxk

    int x, y, z, s, t;
    while(scanf("%d%d%d", &n, &m, &s)!=EOF){
        for(int i=0; i<=n; i++)
            for(int j=0; j<=n; j++)
                w[i][j] = (i==j ? 0 : INF);
        for(int i=0; i<m; i++){
            scanf("%d%d%d", &x, &y, &z);
            w[x][y] = min(w[x][y], z);
        }
        scanf("%d", &t);
        while(t--){
            scanf("%d", &x);
            w[0][x] = 0;       
        }
        dijkstra(0);
        printf("%d\n", d[s] == INF ? -1 : d[s]);
    }
    return 0;
}




思路二

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
#define INF 1e7 + 2
const int maxn = 1000 + 5;

int n, m;
int w[maxn][maxn], d[maxn], v[maxn];

void dijkstra(int s){
    memset(v, 0, sizeof(v));
    for(int i=0; i<=n; i++) d[i] = w[s][i];
    d[s] = 0;
    v[s] = 1;
    for(int i=0; i<=n; i++){
        int x, m = INF;
        for(int y=0; y<=n; y++)
            if(!v[y] && d[y] <= m) m = d[x = y];
        if(m == INF) break;
        v[x] = 1;
        for(int y=0; y<=n; y++) d[y] = min(d[y], d[x] + w[x][y]);
    }
}

int main(){
    #ifdef sxk
        freopen("in.txt", "r", stdin);
    #endif //sxk

    int x, y, z, s, t;
    while(scanf("%d%d%d", &n, &m, &s)!=EOF){
        for(int i=0; i<=n; i++)
            for(int j=0; j<=n; j++)
                w[i][j] = (i==j ? 0 : INF);
        for(int i=0; i<m; i++){
            scanf("%d%d%d", &x, &y, &z);
            w[y][x] = min(w[y][x], z);       //处理成反向图
        }
        dijkstra(s);
        scanf("%d", &t);
        int ans = INF;
        while(t--){
            scanf("%d", &x);
            ans = min(ans, d[x]);           //找最小值
        }
        printf("%d\n", ans == INF ? -1 : ans);
    }
    return 0;
}







hdu 2680 Choose the best route (Dijkstra & 反向图)

标签:

原文地址:http://blog.csdn.net/u013446688/article/details/42915199

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!