zoukankan      html  css  js  c++  java
  • Aizu-2249 Road Construction(dijkstra求最短路)

    Aizu - 2249

    题意:国王本来有一个铺路计划,后来发现太贵了,决定删除计划中的某些边,但是有2个原则,1:所有的城市必须能达到。 2:城市与首都(1号城市)之间的最小距离不能变大。 并且在这2个原则下使得建路消耗最小。

    题解:现在来分析一下,使得n个点联通至少需要n-1条路,然后因为求最小消耗,所以路最多也就只有n-1条,除了首都以外,每一个都市都对应着一条路,我们只需要在dijkstra求最短路的时候,每次更新最短路的距离就更新这个点所对应的边,最后每个城市的点对应的边就是符合要求的边,最后求和一下就是答案了。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<queue>
     5 #include<functional>
     6 using namespace std;
     7 #define ll long long
     8 typedef pair<int, int> pll;
     9 const int INF = 0x3f3f3f3f;
    10 const int N = 10000+5;
    11 struct Node
    12 {
    13     int nt, to, d, c;
    14 }Edge[N*4];
    15 int head[N], dis[N], pre[N];
    16 int cnt = 0, n, m;
    17 void add(int u, int v, int d, int c)
    18 {
    19     Edge[cnt].to = v;
    20     Edge[cnt].d = d;
    21     Edge[cnt].c = c;
    22     Edge[cnt].nt = head[u];
    23     head[u] = cnt++;
    24 }
    25 void dijkstra()
    26 {
    27     memset(dis, INF, sizeof(dis));
    28     dis[1] = 0;
    29     priority_queue<pll, vector<pll>, greater<pll> > q;
    30     q.push(pll(0,1));
    31     while(!q.empty())
    32     {
    33         int u = q.top().second, d = q.top().first;
    34         q.pop();
    35         if(dis[u] != d) continue;
    36         for(int i = head[u]; ~i; i = Edge[i].nt)
    37         {
    38             int v = Edge[i].to;
    39             if(dis[v] > dis[u] + Edge[i].d)
    40             {
    41                 dis[v] = dis[u] + Edge[i].d;
    42                 pre[v] = i;
    43                 q.push(pll(dis[v],v));
    44             }
    45             else if(dis[v] == dis[u]+Edge[i].d && Edge[i].c < Edge[pre[v]].c)
    46             {
    47                 pre[v] = i;
    48                 q.push(pll(dis[v],v));
    49             }
    50         }
    51     }
    52 }
    53 int main()
    54 {
    55     ios::sync_with_stdio(false);
    56     cin.tie(0);
    57     cout.tie(0);
    58     while(cin >> n >> m, n+m)
    59     {
    60         memset(head, -1, sizeof(head));
    61         cnt = 0;
    62         int x, y, d, c;
    63         for(int i = 0; i < m; i++)
    64         {
    65             cin >> x >> y >> d >> c;
    66             add(x,y,d,c);
    67             add(y,x,d,c);
    68         }
    69         dijkstra();
    70         ll ans = 0;
    71         for(int i = 2; i <= n; i++)
    72         {
    73             ans += Edge[pre[i]].c;
    74         }
    75         cout << ans << endl;
    76     }
    77     return 0;
    78 }
  • 相关阅读:
    公用表表达式(CTE)的递归调用
    c# 如何让tooltip显示文字换行
    实战 SQL Server 2008 数据库误删除数据的恢复
    SQL SERVER数据库中 是否可以对视图进行修改删除
    asp.net中实现文件批量上传
    sql server 2008学习2 文件和文件组
    sql server 2008学习3 表组织和索引组织
    sql server 2008学习4 设计索引的建议
    sql server 2008学习10 存储过程
    .net 调用 sql server 自定义函数,并输出返回值
  • 原文地址:https://www.cnblogs.com/MingSD/p/8417834.html
Copyright © 2011-2022 走看看