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 
****************************************************************/ 

  

posted @ 2015-04-10 20:53  我不吃饼干呀  阅读(332)  评论(0编辑  收藏  举报