• CCF 201609-4 交通规划


    问题描述

    试题编号: 201609-4
    试题名称: 交通规划
    时间限制: 1.0s
    内存限制: 256.0MB
    问题描述:
    问题描述
      G国国王来中国参观后,被中国的高速铁路深深的震撼,决定为自己的国家也建设一个高速铁路系统。
      建设高速铁路投入非常大,为了节约建设成本,G国国王决定不新建铁路,而是将已有的铁路改造成高速铁路。现在,请你为G国国王提供一个方案,将现有的一部分铁路改造成高速铁路,使得任何两个城市间都可以通过高速铁路到达,而且从所有城市乘坐高速铁路到首都的最短路程和原来一样长。请你告诉G国国王在这些条件下最少要改造多长的铁路。
    输入格式
      输入的第一行包含两个整数n, m,分别表示G国城市的数量和城市间铁路的数量。所有的城市由1到n编号,首都为1号。
      接下来m行,每行三个整数a, b, c,表示城市a和城市b之间有一条长度为c的双向铁路。这条铁路不会经过a和b以外的城市。
    输出格式
      输出一行,表示在满足条件的情况下最少要改造的铁路长度。
    样例输入
    4 5
    1 2 4
    1 3 5
    2 3 2
    2 4 3
    3 4 2
    样例输出
    11
    评测用例规模与约定
      对于20%的评测用例,1 ≤ n ≤ 10,1 ≤ m ≤ 50;
      对于50%的评测用例,1 ≤ n ≤ 100,1 ≤ m ≤ 5000;
      对于80%的评测用例,1 ≤ n ≤ 1000,1 ≤ m ≤ 50000;
      对于100%的评测用例,1 ≤ n ≤ 10000,1 ≤ m ≤ 100000,1 ≤ a, b ≤ n,1 ≤ c ≤ 1000。输入保证每个城市都可以通过铁路达到首都。
    求解思路:
     
      要使“从所有城市乘坐高速铁路到首都的最短路程和原来一样长”,容易想到从首都结点开始做单源最短路,修建的高速铁路一定在这些最短路上。
      如果把每个结点到首都的最短路径上的边都修建成高速铁路,则显然任何两个城市间都可以以首都作为中继结点,通过高速铁路互相到达。
      如果同时存在多条最短路径,应该选择扩展时用到的边距离最小的那一条。
      很显然,如果利用dijkstra算法从1结点开始往外扩展,每扩展一个结点刚好就要多修一条高速铁路,因此在做求解最短路时,可以记录下每个结点扩展时所需要多修建的这条高速铁路的长度,在扩展时遇到有多种可能的最短路情况时,记录下边权最小的一个。
     
    代码如下:
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int MAX=10005;
     5 const int INF=1e9;
     6 int n,m;
     7 
     8 struct HeapNode
     9 {
    10     int d,u;
    11     bool operator<(const HeapNode& r)const
    12     {
    13         return d>r.d;
    14     }
    15 };
    16 
    17 struct Edge
    18 {
    19     int to,dis;
    20 };
    21 
    22 vector<Edge>G[MAX];
    23 int d[MAX];
    24 bool vis[MAX];
    25 
    26 int cost [MAX];
    27 void dijkstra(int s)
    28 {
    29     priority_queue<HeapNode>Q;
    30     for(int i=1;i<=n;i++)
    31         d[i]=cost[s]=INF;
    32     d[s]=cost[s]=0;
    33     memset(vis,0,sizeof vis);
    34 
    35     Q.push({0,s});
    36 
    37     while(!Q.empty())
    38     {
    39         HeapNode x=Q.top();
    40         Q.pop();
    41 
    42         int u=x.u;
    43 
    44         if(vis[u])
    45             continue;
    46         vis[u]=true;
    47 
    48         for(int i=0;i<G[u].size();i++)
    49         {
    50             Edge& e=G[u][i];
    51             if(d[e.to]>d[u]+e.dis)
    52             {
    53                 d[e.to]=d[u]+e.dis;
    54                 Q.push({d[e.to],e.to});
    55                 cost[e.to]=e.dis;
    56             }
    57             //记录下边权最小的一个
    58            if(d[e.to]==d[u]+e.dis&&cost[e.to]>e.dis)
    59                 cost[e.to]=e.dis;
    60         }
    61     }
    62 }
    63 
    64 int main()
    65 {
    66     scanf("%d%d",&n,&m);
    67         for(int i=0;i<m;i++)
    68         {
    69             int a,b,c;
    70             scanf("%d%d%d",&a,&b,&c);
    71             G[a].push_back({b,c});
    72             G[b].push_back({a,c});
    73         }
    74 
    75         dijkstra(1);
    76         int ans=0;
    77          for(int i=2;i<=n;i++)
    78             ans+=cost[i];
    79 
    80          printf("%d
    ",ans);
    81 
    82     return 0;
    83 }
     
  • 相关阅读:
    初次接触json...
    vector algorithm find
    网站安全(13) ——目录穿越漏洞(Directory Traversal)
    网站安全(20) —— 语义URL攻击
    网站安全(7) —— PHP文件包含漏洞介绍
    让PHP更快的提供文件下载
    PHP中关于include()和require() 的区别问题
    PHP中 获取全路径的文件的扩展名
    MySQL varchar计算:求列的数目和计算N的最大值
    jmeter使用分享
  • 原文地址:https://www.cnblogs.com/from00/p/6575487.html
Copyright © 2020-2023  润新知