zoukankan      html  css  js  c++  java
  • 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 }
     
  • 相关阅读:
    NYOJ 625 笨蛋的难题(二)
    NYOJ 102 次方求模
    ZJU Least Common Multiple
    ZJUOJ 1073 Round and Round We Go
    NYOJ 709 异形卵
    HDU 1279 验证角谷猜想
    BNUOJ 1015 信息战(一)——加密程序
    HDU 1202 The calculation of GPA
    "蓝桥杯“基础练习:字母图形
    "蓝桥杯“基础练习:数列特征
  • 原文地址:https://www.cnblogs.com/from00/p/6575487.html
Copyright © 2011-2022 走看看