1225: 最小花费

来源:互联网 发布:淘宝推广技巧视频 编辑:程序博客网 时间:2024/05/18 01:37
Description现在给出N个城市,城市之间共有M条道路。道路表示的方法是<u,v,w>,代表从编号为u的城市,到标号为v的城市有条花费为w的道路。现在我们从编号为S的城市出发,目的地是编号为T的城市。但是我们在旅途中从u号城市到v号城市花费不只是他们的道路的花费w,还要加上以前的所有花费的一半,向下取整。Input第一行一个正整数T<=10,代表测试数据个数对每组测试数据:第一行两个正整数N,M代表城市的个数,和道路的个数2<=N<=10000<=M<=100000然后给出M行,每行三个正整数u,v,w代表每条道路的信息,道路都是双向的u,v,w代表从编号为u的城市,到编号为v的城市有一条花费为w的道路城市的编号是从1N的,w的范围是[1,10000]最后一行是两个正整数S,T代表出发地和目的地Output如果不存在从S到T的路径输出-1,否则输出最小花费,每组测试数据的输出占一行Sample Input23 21 2 32 3 41 32 01 2Sample Output8-1HINT从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 ****************************************************************/ 
0 0