zoukankan      html  css  js  c++  java
  • 51nod 1443 路径和树(最短路)

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1443

    1443 路径和树 

    题目来源: CodeForces
    基准时间限制:1.5 秒 空间限制:131072 KB 分值: 160 难度:6级算法题
     

    给定一幅无向带权连通图G = (V, E) (这里V是点集,E是边集)。从点u开始的最短路径树是这样一幅图G1 = (V, E1),其中E1是E的子集,并且在G1中,u到所有其它点的最短路径与他在G中是一样的。

    现在给定一幅无向带权连通图G和一个点u。你的任务是找出从u开始的最短路径树,并且这个树中所有边的权值之和要最小。

    Input
    单组测试数据。
    第一行有两个整数n和m(1 ≤ n ≤ 3*10^5, 0 ≤ m ≤ 3*10^5),表示点和边的数目。
    接下来m行,每行包含3个整数 ui, vi, wi ,表示ui和vi之间有一条权值为wi的无向边(1 ≤ ui,vi ≤ n, 1 ≤ wi ≤ 10^9)。
    输入保证图是连通的。
    最后一行给出一个整数u (1 ≤ u ≤ n),表示起点。
    Output
    输出这棵树的最小的权值之和。
    Input示例
    3 3
    1 2 1
    2 3 1
    1 3 2
    3
    Output示例
    2

    题解:开始想着先求最短路再求一次最小生成树,,,后来发现只要在求最短路时记录最小前驱边权就行...

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N = 300005;
     4 const int M = 300005;
     5 typedef long long ll;
     6 const ll INF = 1e18;
     7 struct edge {
     8     int to;
     9     ll cost;
    10     edge(int _to, ll _cost):to(_to),cost(_cost){}
    11 };
    12 typedef pair<ll, int> P;// first是最短距离,second是顶点的编号
    13 int V;
    14 vector<edge>G[N];
    15 ll d[N];
    16 ll pre[N];
    17 void dij(int s) {
    18     priority_queue<P, vector<P>, greater<P> > que;
    19     for(int i = 0; i <= V; ++i) d[i] = INF;
    20     d[s] = 0;
    21     que.push(P(0, s));
    22 
    23     while(!que.empty()) {
    24         P p = que.top(); que.pop();
    25         int v = p.second;
    26         if(d[v] < p.first) continue;
    27         int num = G[v].size();
    28         for(int i = 0; i < num; ++i) {
    29             edge e = G[v][i];
    30             if(d[e.to] > d[v] + e.cost) {
    31                 pre[e.to] = e.cost;
    32                 d[e.to] = d[v] + e.cost;
    33                 que.push(P(d[e.to], e.to));
    34             }
    35             else if(d[e.to] == d[v] + e.cost) {
    36                 pre[e.to] = min(pre[e.to], e.cost);
    37             }
    38         }
    39     }
    40 }
    41 
    42 int main() {
    43     int n, m, i, j, u, v, st;
    44     ll w;
    45     memset(pre, 0, sizeof(pre));
    46     scanf("%d%d", &n, &m);
    47     V = n;
    48     while(m--) {
    49         scanf("%d%d%lld", &u, &v, &w);
    50         G[u].push_back(edge(v, w));
    51         G[v].push_back(edge(u, w));
    52     }
    53     scanf("%d", &st);
    54     dij(st);
    55     ll ans = 0;
    56     //最小前驱边权和
    57     for(i = 1; i <= n ;++i) {
    58         ans += pre[i];
    59     }
    60     printf("%lld
    ", ans);
    61     return 0;
    62 }
    View Code
  • 相关阅读:
    微软RPC技术学习小结
    [COM Interop学习小结]实现一个C#调用C++的示例
    [一个小问题]Mainfest配置文件的version问题小结
    【小结】IIS7下的Http Native Module开发
    Active Sync与IIS7 Classic&Integrated模式,Exchange 2007&2010的关系
    是否能在构造函数,析构函数中抛出异常?
    Trouble Shooting的一些感想(实时补充)
    python中 try、except、finally 的执行顺序
    Hessian怎样实现远程调用
    mysql的三种驱动类型
  • 原文地址:https://www.cnblogs.com/GraceSkyer/p/8781235.html
Copyright © 2011-2022 走看看