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\n", ans);
61     return 0;
62 }
View Code

 

posted @ 2018-04-10 18:11  GraceSkyer  阅读(461)  评论(0编辑  收藏  举报

~~~~~~ACM大牛语录,激励一下~~~~~~

为了世界的和平,为了女生的安全,我拼命做题,做题,做题!

用最短的时间,刷最多的题!

给我一滴泪,我就看到了你全部的海洋!

seize the hour, seize the day.

人生难免有无奈,幸福走远了,或是感叹幸福来迟了.其实我一直相信,无论手中的幸福是多么微不足道的感觉,我会把握住那每一分,每一秒,当幸福依旧像那百鸟般飞逝,终究无法掌握时,我会感谢它,曾经降临过!

A自己的题,让别人郁闷去吧

WA肠中过,AC心中留 TLE耳边过,AC特别牛

天然的悲苦和伤逝,过去有过,以后还会有

^*^一步一步往上爬^*^

AC就像练级,比赛就像PK. 练级不如PK好玩

其实,世上本没有ACM,AC的人多了,也便有了!

AC无止尽~ Seek you forever~

找呀找呀找水题,找到一个AC一个呀!

AC是检验程序的唯一标准。

真的猛士,敢于直面惨淡的人生,敢于正视淋漓的鲜血……