1225: 最小花费

Description

现在给出N个城市,城市之间共有M条道路。道路表示的方法是<u,v,w>,

代表从编号为u的城市,到标号为v的城市有条花费为w的道路。

现在我们从编号为S的城市出发,目的地是编号为T的城市。

但是我们在旅途中从u号城市到v号城市花费不只是他们的道路的花费w,

还要加上以前的所有花费的一半,向下取整。



Input

第一行一个正整数T<=10,代表测试数据个数

对每组测试数据:

第一行两个正整数N,M代表城市的个数,和道路的个数

2<=N<=1000

0<=M<=100000

然后给出M行,每行三个正整数u,v,w代表每条道路的信息,道路都是双向的

u,v,w代表从编号为u的城市,到编号为v的城市有一条花费为w的道路

城市的编号是从1N的,w的范围是[1,10000]

最后一行是两个正整数S,T代表出发地和目的地



Output

如果不存在从S到T的路径输出-1,否则输出最小花费,每组测试数据的输出占一行



Sample Input

2

3 2

1 2 3

2 3 4

1 3

2 0

1 2



Sample Output

8

-1



HINT

从12,花费3+0/2=323,花费4+3/2=5

总花费为8



输入数据较大,不要用cin读入数据

乍一看以为是最短路,仔细一看“但是我们在旅途中从u号城市到v号城市花费不只是他们的道路的花费w,还要加上以前的所有花费的一半,向下取整。”这怎么能是最短路嘞~
后来问了别人,好吧,还是最短路。
自己学的太死了。
只是把最短路更新的语句改了一下,基本没动。

#include <iostream> 

#include <cstring> 

#include <cstdio> 

using namespace std; 



const int MAX = 1005; 

const int INF = 0x7ffffff; 



int mp[MAX][MAX]; 

int vis[MAX]; 

int dis[MAX]; 



int dij(int n, int s, int e) 

{ 

    int m; 

    int k; 

    memset(vis, 0, sizeof(vis)); 

    for (int i = 0; i < n; i++) 

    { 

        dis[i] = mp[s][i]; 

    } 

    vis[s] = 1; 

    for (int i = 1; i < n; i++) 

    { 

        m = INF; 

        k = 1; 

        for (int j = 0; j < n; j++) 

        { 

            if (!vis[j] && m > dis[j]) 

            { 

                m = dis[j]; 

                k = j; 

            } 

        } 

        vis[k] = 1; 

        if (k == e) 

            return m; 

        for (int j = 0; j < n; j++) 

        { //只有这里需要改动一下

            if (!vis[j] && dis[j] > dis[k] + dis[k] / 2 + mp[k][j]) 

            { 

                dis[j] = dis[k] + dis[k] / 2 + mp[k][j];

            } 

        } 

    } 

    return dis[e]; 

} 

int main() 

{ 

    int t; 

    int m, n; 

    int a, b, c; 

    int s, e; 

    scanf("%d", &t); 

    while (t--) 

    { 

        scanf("%d%d", &n, &m); 

        for (int i = 0; i < n; i++) 

        { 

            for (int j = 0; j < n; j++) 

            { 

                if (i == j) 

                    mp[i][j] = 0; 

                else

                    mp[i][j] = INF; 

            } 

        } 

        for (int i = 0; i < m; i++) 

        { 

            scanf("%d%d%d", &a, &b, &c); 

            if (mp[a - 1][b - 1] > c) 

                mp[a - 1][b - 1] = mp[b - 1][a - 1] = c; 

        } 

        scanf("%d%d", &s, &e); 

        int ans = dij(n, s - 1, e - 1); 

        if (ans == INF) ans = -1; 

        printf("%d\n", ans); 

    } 

    return 0; 

} 



/************************************************************** Problem: 1225 User: Language: C++ Result: Accepted Time:972 ms Memory:5600 kb ****************************************************************/ 



你可能感兴趣的:(1225: 最小花费)