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
 /*
利用spfa求出最短路之后, 然后根据dist数组中的值去寻找某个点最短路径的上一条边,然后对这些边求最小生成树
这里会出现一个问题,是否在求出每个点的最短路的上一条边之后,这个子图就变成了一个最小生成树了呢?
有可能,但也有可能出现这种情况:
某个点到起点的最短路可以通过多种路径实现,这种情况下,但是如果不用最小生成树的话,无法确定最小生成树中是哪一条路径
因此需要求最短路
ex:
6 8
1 2 30
1 3 20
2 3 50
4 2 100
2 5 40
3 5 10
3 6 50
5 6 60
4
答案为:
230
*/
#include<bits/stdc++.h>
#define LL long long
#define MAXN 300005
using namespace std;
int n, m;
LL dist[MAXN];
int inQueue[MAXN], root[MAXN];
int in[MAXN];
vector <pair< int, LL> > G[MAXN];
queue <int> Q;
struct Edge
{
int u, v;
LL cost;
Edge(int U = -, int V = -, LL C = -)
{
u = U;
v = V;
cost = C;
}
bool operator < (const Edge& x) const
{
return cost < x.cost;
}
};
vector <Edge> edge;
int findRoot(int x)
{
if(x == root[x]) return x;
else
return root[x] = findRoot(root[x]);
}
void unite(int x, int y)
{
x = findRoot(x);
y = findRoot(y);
if(x == y) return;
root[x] = root[y];
}
void spfa(int star)
{
memset(dist, -, sizeof(dist));
memset(inQueue, , sizeof(inQueue));
while(!Q.empty()) Q.pop();
dist[star] = ;
inQueue[star] = ;
Q.push(star);
while(!Q.empty())
{
int now = Q.front();
Q.pop();
inQueue[now] = ;
int siz = G[now].size();
for(int i = ; i < siz; i++)
{
int v = G[now][i].first;
LL cost = G[now][i].second;
if(dist[v] == - || dist[v] > dist[now] + cost)
{
dist[v] = dist[now] + cost;
if(!inQueue[v])
{
inQueue[v] = ;
Q.push(v);
}
}
}
}
}
LL Kruskal()
{
LL res = ;
memset(in, , sizeof(in));
sort(edge.begin(), edge.end());
int siz = edge.size();
for(int i = ; i < siz; i++)
{
int u = edge[i].u, v = edge[i].v;
LL cost = edge[i].cost;
if(in[v] || findRoot(u) == findRoot(v)) continue;
in[v] = ;
unite(u, v);
res += cost;
}
return res;
}
int main()
{
freopen("data.in","r",stdin);
while(scanf("%d%d", &n, &m) != EOF)
{
for(int i = ; i <= n; i++)
{
G[i].clear();
root[i] = i;
}
for(int i = ; i < m; i++)
{
int u, v, cost;
scanf("%d%d%d", &u, &v, &cost);
G[u].push_back(make_pair(v, (LL)cost));
G[v].push_back(make_pair(u, (LL)cost));
}
int star;
scanf("%d", &star);
spfa(star);
edge.clear();
LL sum=;
// cout<<star<<endl;
// for(int i=1;i<=n;i++){
// cout<<dist[i]<<"\t";
// }
// cout<<endl;
for(int i = ; i <= n; i++)
{
//cout<<22222<<endl;
///if(i!=star){
int siz = G[i].size();
//cout<<siz<<endl<<endl;
for(int j = ; j < siz; j++)
{ int v = G[i][j].first;
LL cost = G[i][j].second;
if(dist[v] == dist[i] + cost)
{
edge.push_back(Edge(i, v, cost));
//sum+=cost;
//cout<<111111<<endl;
//cout<<i<<"\t"<<v<<"\t"<<sum<<endl;
//break;
}
}
///}
}
printf("%lld\n", Kruskal());
//printf("%lld\n",sum);
}
return ;
}

51nod11443-路径和树(图论,最短路,最小生成树)的更多相关文章

  1. 51nod 1443 路径和树(最短路)

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1443 1443 路径和树 题目来源: CodeForces ...

  2. 图论(最短路&最小生成树)

    图论 图的定义与概念 图的分类 图,根据点数和边数可分为三种:完全图,稠密图与稀疏图. 完全图,即\(m=n^2\)的图\((m\)为边数,\(n\)为点数\()\).如: 1 1 0 1 2 1 1 ...

  3. 51nod 1443 路径和树(最短路树)

    题目链接:路径和树 题意:给定无向带权连通图,求从u开始边权和最小的最短路树,输出最小边权和. 题解:构造出最短路树,把存留下来的边权全部加起来.(跑dijkstra的时候松弛加上$ < $变成 ...

  4. [BZOJ1576] [BZOJ3694] [USACO2009Jan] 安全路径(最短路径+树链剖分)

    [BZOJ1576] [BZOJ3694] [USACO2009Jan] 安全路径(最短路径+树链剖分) 题面 BZOJ1576和BZOJ3694几乎一模一样,只是BZOJ3694直接给出了最短路树 ...

  5. Day3 最短路 最小生成树 拓扑排序

    Day3 最短路 最小生成树 拓扑排序 (一)最短路 一.多源最短路 从任意点出发到任意点的最短路 1. Floyd \(O(n^3)\) for(int k=1;k<=n;k++) for(i ...

  6. python图论包networks(最短路,最小生成树带包)

    官方文档: https://networkx.github.io/documentation/networkx-1.10/reference/algorithms.html 最短路和最小生成树: im ...

  7. 51nod 1443 路径和树——最短路生成树

    题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1443 不只是做一遍最短路.还要在可以选的边里选最短的才行. 以为是 ...

  8. 图论--最短路--dijkstra(含路径输出)模板

    #include<iostream> #include<stack> #include<queue> #include<cstring> #includ ...

  9. 图论--最短路--Floyd(含路径输出)

    #include<bits/stdc++.h> using namespace std; #define INF 0x3f3f3f3f #define maxn 1005 int D[ma ...

  10. 树的问题小结(最小生成树、次小生成树、最小树形图、LCA、最小支配集、最小点覆盖、最大独立集)

    树的定义:连通无回路的无向图是一棵树. 有关树的问题: 1.最小生成树. 2.次小生成树. 3.有向图的最小树形图. 4.LCA(树上两点的最近公共祖先). 5.树的最小支配集.最小点覆盖.最大独立集 ...

随机推荐

  1. [LGP4859,...] 一类奇怪的容斥套DP

    漫山遍野都是fake的光影. 题目 [LGP4859] 已经没有什么好害怕的了 给定两个长度为n的数组a和b,将a中元素与b中元素配对,求满足ai>bj的配对(i,j)个数减去满足ai<b ...

  2. linux 三剑客之awk总结

    AWK 1.begin end使用 cat /tmp/passwd |awk -F ':' 'BEGIN {print "hello"} {print $1"\t&quo ...

  3. MySQL的事务和锁

    MySQL的事务和锁   阅读目录 什么是事务 事务:是数据库操作的最小工作单元,是作为单个逻辑工作单元执行的一系列操作:这些操作作为一个整体一起向系统提交,要么都执行.要么都不执行:事务是一组不可再 ...

  4. pwd命令和修改PS1环境变量在bash行的显示

    一.pwd:显示当前所在的位置 语法 pwd [选项] ... 描述       打印当前工作目录的完整文件名. -L,--logical              从环境使用PWD,即使它包含符号链 ...

  5. calc,support,media各自的含义及用法

    @support:用于检测浏览器是否支持CSS某个属性,即条件判断,如果支持某个属性,可以写一套样式,如果不支持某属性,提供另一套样式作为替补. calc():用于计算动态函数值,支持“+”,“-”, ...

  6. ccs之经典布局(一)(水平垂直居中)

    经典的css布局有以下几种,下面分别用不同的方法进行实现且进行对比. 一.水平居中 水平居中布局指的是当前元素在父级元素的容器中,水平方向上显示的是居中的,有以下几种方式来完成布局: 1.margin ...

  7. hiper、sitespeed性能工具

    https://github.com/pod4g/hiper   hiper:   A statistical analysis tool for performance testing https: ...

  8. linux 之实现定时任务

    一.方式一 (1)命令行 的方法: 一.方式一 需求:每分钟执行一次/etc 目录的添加 到/tmp/a.txt 中 (1) touch a.txt创建文件 (2) crotab -e 进行任务的定制 ...

  9. python 写入JSON中文乱码解决方法

    在将一个字典添加入json中时多加入一个参数就可以了 json.dumps(dict(item), ensure_ascii=False) 例子 with open('zh-cn.json','w', ...

  10. tensorflow源码分析

    前言: 一般来说,如果安装tensorflow主要目的是为了调试些小程序的话,只要下载相应的包,然后,直接使用pip install tensorflow即可. 但有时我们需要将Tensorflow的 ...