• 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
    ", ans); 
        } 
        return 0; 
    } 
    
    /************************************************************** 
        Problem: 1225 
        User: 
        Language: C++ 
        Result: Accepted 
        Time:972 ms 
        Memory:5600 kb 
    ****************************************************************/ 
    

      

  • 相关阅读:
    python 爬取网络小说 清洗 并下载至txt文件
    2020.11.25收获
    2020.11.24收获
    2020.11.23收获
    2020.11.22收获
    2020.11.21收获
    Java学习11.21(使用 Servlet 完成控制)
    Java学习11.20
    Java学习11.19(学习servlet第三天)
    Java学习11.17(人口普查前端页面)
  • 原文地址:https://www.cnblogs.com/wenruo/p/4492692.html
Copyright © 2020-2023  润新知