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

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= Then follow m lines ,each line contains three integers p , q , t (0 Then a line with an integer w(0
 

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
2009浙江大学计算机研考复试(机试部分)——全真模拟




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


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

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

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

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



AC代码:


思路一

#include 
#include 
#include 
#include 
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




思路二

#include 
#include 
#include 
#include 
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







你可能感兴趣的:(HDU,最短路径)