51nod11443-路径和树(图论,最短路,最小生成树)
给定一幅无向带权连通图G = (V, E) (这里V是点集,E是边集)。从点u开始的最短路径树是这样一幅图G1 = (V, E1),其中E1是E的子集,并且在G1中,u到所有其它点的最短路径与他在G中是一样的。
现在给定一幅无向带权连通图G和一个点u。你的任务是找出从u开始的最短路径树,并且这个树中所有边的权值之和要最小。
单组测试数据。
第一行有两个整数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),表示起点。
输出这棵树的最小的权值之和。
3 3
1 2 1
2 3 1
1 3 2
3
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-路径和树(图论,最短路,最小生成树)的更多相关文章
- 51nod 1443 路径和树(最短路)
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1443 1443 路径和树 题目来源: CodeForces ...
- 图论(最短路&最小生成树)
图论 图的定义与概念 图的分类 图,根据点数和边数可分为三种:完全图,稠密图与稀疏图. 完全图,即\(m=n^2\)的图\((m\)为边数,\(n\)为点数\()\).如: 1 1 0 1 2 1 1 ...
- 51nod 1443 路径和树(最短路树)
题目链接:路径和树 题意:给定无向带权连通图,求从u开始边权和最小的最短路树,输出最小边权和. 题解:构造出最短路树,把存留下来的边权全部加起来.(跑dijkstra的时候松弛加上$ < $变成 ...
- [BZOJ1576] [BZOJ3694] [USACO2009Jan] 安全路径(最短路径+树链剖分)
[BZOJ1576] [BZOJ3694] [USACO2009Jan] 安全路径(最短路径+树链剖分) 题面 BZOJ1576和BZOJ3694几乎一模一样,只是BZOJ3694直接给出了最短路树 ...
- Day3 最短路 最小生成树 拓扑排序
Day3 最短路 最小生成树 拓扑排序 (一)最短路 一.多源最短路 从任意点出发到任意点的最短路 1. Floyd \(O(n^3)\) for(int k=1;k<=n;k++) for(i ...
- python图论包networks(最短路,最小生成树带包)
官方文档: https://networkx.github.io/documentation/networkx-1.10/reference/algorithms.html 最短路和最小生成树: im ...
- 51nod 1443 路径和树——最短路生成树
题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1443 不只是做一遍最短路.还要在可以选的边里选最短的才行. 以为是 ...
- 图论--最短路--dijkstra(含路径输出)模板
#include<iostream> #include<stack> #include<queue> #include<cstring> #includ ...
- 图论--最短路--Floyd(含路径输出)
#include<bits/stdc++.h> using namespace std; #define INF 0x3f3f3f3f #define maxn 1005 int D[ma ...
- 树的问题小结(最小生成树、次小生成树、最小树形图、LCA、最小支配集、最小点覆盖、最大独立集)
树的定义:连通无回路的无向图是一棵树. 有关树的问题: 1.最小生成树. 2.次小生成树. 3.有向图的最小树形图. 4.LCA(树上两点的最近公共祖先). 5.树的最小支配集.最小点覆盖.最大独立集 ...
随机推荐
- Mysql workbench 字段类型(转载)
转载自:https://blog.csdn.net/j_h_xie/article/details/52924521 项目初始,在使用workbench建表时,字段中有PK,NN,UQ,BIN,UN, ...
- nginx配置ssi实现页面拆分
在做一个网站时,页面上会有很多重复的内容,每个页面写一遍很冗余,修改时还容易遗漏,所以可以把公共的部分写好,放在单独的HTML中,用时引用就行了. nginx配置ssi可以将单个页面拆分成一个一个的小 ...
- python中format格式化函数
http://www.runoob.com/python/att-string-format.html
- 小白学习tornado第二站-tornado简单介绍
tornado基本web应用结构 分为两大块类 Application对象(只会实例化一次) 路由表URl映射 (r'/', MainHandler) 关键词参数settings RequestHan ...
- spark教程(14)-共享变量
spark 使用的架构是无共享的,数据分布在不同节点,每个节点有独立的 CPU.内存,不存在全局的内存使得变量能够共享,驱动程序和任务之间通过消息共享数据 举例来说,如果一个 RDD 操作使用了驱动程 ...
- MySQL中文正常而mybatis查询出现乱码的解决方案
解决方案是在spring-mvc.xml文件中,加入 <mvc:annotation-driven> <mvc:message-converters> <bean cla ...
- Java集合框架中的元素
之前有一篇笔记,讲的是集合和泛型,这几天看Java集合中几个接口的文档,思绪非常混乱,直到看到Oracle的“The Collections Framwork”的页面,条理才清晰些,现在进行整理. 一 ...
- django-Auth模块(详细介绍)
转载自https://www.cnblogs.com/liuqingzheng/articles/9628105.html 1 Auth模块是什么 Auth模块是Django自带的用户认证模块: 我们 ...
- 使用@ResponseBody输出JSON
添加jackson依赖 添加@ResponseBody 测试: 原理: 当一个处理请求的方法标记为@ResponseBody时,就说明该方法需要输出其他视图(json.xml),SpringMVC通过 ...
- @RequestMapping-标准映射和Ant风格的映射
4.@RequestMapping 如果value不以“/”开头,SpringMVC会自动添加“/” 4.1.@RequestMapping映射 4.1.1.标准URL映射 4.1.2.Ant风格的U ...