【最短路】道路重建 @upcexam5797
时间限制: 1 Sec 内存限制: 128 MB 题目描述
小L的家乡最近遭遇了一场洪水,城市变得面目全非,道路也都被冲毁了。生活还要继续,于是市政府决定重建城市中的道路。
在洪水到来前,城市中共有n个区域和m条连接这些区域的双向道路, 道路连通了所有的区域,为了方便人们的出行,只能重建这些原有的道路,
不能建新的道路。编号为s的区域是市政广场,市政府希望重建的道路能够 使得所有区域到市政广场的最短路与受灾前保持不变,同时为了节约救灾
经费,还要使得修建的所有道路的长度和尽可能小。 小L为了拯救心爱的家乡,决定站出来,成为优秀的青年理论计算机科
学家,于是马上投入到了对这个问题的研究中。你能帮帮小L吗?输入
第一行两个整数n和m,表示区域与道路的个数。
接下来m行,每行三个正整数u,v和w,描述一条连接u和v、长为w的道路。 最后一行,一个正整数s,表示市政广场的编号。输出
输出一个整数,表示最小长度和。 样例输入 5 7 1 2 1 2 3 4 2 4 2 4 3 2 5 2 2 4 5 1 5 1 1
2 样例输出 6 提示 最优方案是重建1-2,1-5,2-4,4-3的道路,此时所有区域到达区域2的最短路分别是1, 0, 4, 2,
2,道路长度和是1 + 1 + 2 + 2 = 6。 对于20%的数据,n ≤ 10, m ≤ 20; 对于另外30%的数据,边权不超过2;
对于100%的数据,1 ≤ n ≤ 105, n − 1 ≤ m ≤ 2 ∗ 105, 1 ≤ w ≤ 109。来源 2018山东冬令营
先跑一遍Dijkstra,求出原点到每个点的最短路径长度d[i],
再一模一样跑一遍Dijkstra,只不过在每次更新操作时,维护每个点的最小入度值。
具体就是 如果dd[u](当前求得的原点到u的最短路长度)+e(u,v).w == d[v](第一次求得的最短路),
就维护d2[v] = min(d2[v],e(u,v).w);
#define FILE() freopen("../../in.txt","r",stdin)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//const int MOD = 1e9+7;
const int maxn = 100005,maxm = 200005;
const ll INF = 1e16+5;
int n,m,head[maxn],cnt;
ll d[maxn],dd[maxn],d2[maxn];
struct edge {
int v,nex;
ll w;
} ed[maxm*2];
struct node1{
int num,len;
};
struct node2{
int num,len;
};
bool operator < (node1 a,node1 b){
return d[a.num]>d[b.num];
}
bool operator < (node2 a,node2 b){
return dd[a.num]>dd[b.num];
}
priority_queue <node1> q;
priority_queue <node2> qq;
void addedge(int _u,int _v,ll _w) {
cnt++;
ed[cnt].v = _v;
ed[cnt].w = _w;
ed[cnt].nex = head[_u];
head[_u] = cnt;
}
void dij1(int start) {
for(int i=1;i<=n;i++)d[i] = INF;
d[start] = 0;
while(!q.empty())q.pop();
q.push((node1){start,0});
while(!q.empty()) {
int cur = q.top().num,len = q.top().len;
q.pop();
if(d[cur]<len)continue;
for(int i=head[cur]; i; i=ed[i].nex) {
int v=ed[i].v;
if(d[v]>d[cur]+ed[i].w){
d[v] = d[cur]+ed[i].w;
q.push((node1){v,d[v]});
}
}
}
}
void dij2(int start){
for(int i=1;i<=n;i++)dd[i] = d2[i] = INF;
dd[start] = d2[start] = 0;
while(!qq.empty())qq.pop();
qq.push((node2){start,0});
while(!qq.empty()) {
int cur = qq.top().num,len = qq.top().len;
qq.pop();
if(dd[cur]<len)continue;
for(int i = head[cur];i;i=ed[i].nex){
int v=ed[i].v;
if(dd[v]>dd[cur]+ed[i].w){
dd[v] = dd[cur]+ed[i].w;
qq.push((node2){v,dd[v]});
}
if(d[v]==dd[cur]+ed[i].w){
d2[v] = min(d2[v],ed[i].w);
}
}
}
}
int main() {
// FILE();
// freopen("../../out.txt","w",stdout);
cin>>n>>m;
for(int i=0; i<m; i++) {
int u,v;
ll w;
scanf("%d%d%lld",&u,&v,&w);
addedge(u,v,w);
addedge(v,u,w);
}
int s;
cin>>s;
dij1(s);
dij2(s);
ll sum = 0;
for(int i=1;i<=n;i++)sum+=d2[i];
cout<<sum<<endl;
return 0;
}
【最短路】道路重建 @upcexam5797的更多相关文章
- 洛谷 P3905 道路重建 题解
P3905 道路重建 题目描述 从前,在一个王国中,在\(n\)个城市间有\(m\)条道路连接,而且任意两个城市之间至多有一条道路直接相连.在经过一次严重的战争之后,有\(d\)条道路被破坏了.国王想 ...
- P1359 租用游艇 && P3905 道路重建 ------Floyd算法
P1359 租用游艇 原题链接https://www.luogu.org/problemnew/show/P1359 P3905 道路重建 原题链接https://www.luogu.org/ ...
- P3905 道路重建
P3905 道路重建我一开始想错了,我的是类似kruskal,把毁坏的边从小到大加,并且判断联通性.但是这有一个问题,你可能会多加,就是这条边没用,但是它比较小,你也加上了.居然还有10分,数据也是水 ...
- 洛谷——P3905 道路重建
P3905 道路重建 题目描述 从前,在一个王国中,在n个城市间有m条道路连接,而且任意两个城市之间至多有一条道路直接相连.在经过一次严重的战争之后,有d条道路被破坏了.国王想要修复国家的道路系统,现 ...
- 洛谷 P3905 道路重建
题目描述 从前,在一个王国中,在n个城市间有m条道路连接,而且任意两个城市之间至多有一条道路直接相连.在经过一次严重的战争之后,有d条道路被破坏了.国王想要修复国家的道路系统,现在有两个重要城市A和B ...
- [JZOJ 5465] [NOIP2017提高A组冲刺11.9] 道路重建 解题报告 (e-dcc+树的直径)
题目链接: http://172.16.0.132/senior/#main/show/5465 题目: 小X所居住的X国共有n个城市,有m条无向道路将其连接.作为一个统一的国家,X 城的任意两个城市 ...
- 洛谷P3905 道路重建
题目:https://www.luogu.org/problemnew/show/P3905 分析: 此题是显然的最短路算法,只是看到一起删掉的一堆边感到十分棘手,而且还要求出的是最短添加边的总长度 ...
- SPFA--P3905 道路重建
题目描述 从前,在一个王国中,在n个城市间有m条道路连接,而且任意两个城市之间至多有一条道路直接相连.在经过一次严重的战争之后,有d条道路被破坏了.国王想要修复国家的道路系统,现在有两个重要城市A和B ...
- 【洛谷P1272】道路重建
题目大意:给定一个 N 个节点的树,求至少剪掉多少条边才能使得从树中分离出一个大小为 M 的子树. 题解:考虑树形 dp,定义 \(dp[u][i][t]\) 为以 u 为根节点与前 i 个子节点构成 ...
随机推荐
- 【bzoj4817】[Sdoi2017]树点涂色&&bzoj3779-重组病毒
题解: 两道几乎差不多的题(所以说当年sdoi考了道原题) 都是将树上一段改为新颜色询问颜色数目 可以把改成新颜色这个操作看成access操作 然后通过线段树+dfs序来维护 另外换根了为什么还可以用 ...
- 一起学Hive——详解四种导入数据的方式
在使用Hive的过程中,导入数据是必不可少的步骤,不同的数据导入方式效率也不一样,本文总结Hive四种不同的数据导入方式: 从本地文件系统导入数据 从HDFS中导入数据 从其他的Hive表中导入数据 ...
- python全栈开发day57- pymysql、视图、触发器、函数
一.昨日内容回顾 1.单表查询 优先级 from where group by having select distinct order by limit 2 . 多表查询 inner join... ...
- Trident中的DRPC实现
一:介绍 1.说明 Storm里面引入DRPC主要是利用storm的实时计算能力来并行化CPU intensive的计算.DRPC的storm topology以函数的参数流作为输入,而把这些函数调用 ...
- day 74ajax
w3school地址ajax教程 ajax定义: AJAX(Asynchronous Javascript And XML) 翻译成中文就是'异步JavaScript和XML',也就是使用JavaSc ...
- 2013年蓝桥杯省赛C/C++A组真题解析
1.高斯日记 大数学家高斯有个好习惯:无论如何都要记日记. 他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210 后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的 ...
- 解决UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position
最近用Python写了些爬虫,在爬取一个gb2312的页面时,抛出异常: UnicodeEncodeError: 'ascii' codec can't encode characters in po ...
- 问题 L: An Invisible Hand - (2018年第二阶段个人训练赛第三场)
题目描述 There are N towns located in a line, conveniently numbered 1 through N. Takahashi the merchant ...
- HDU 1533 Going Home (最大权完美匹配)
<题目链接> 题目大意:给你一张地图,地图上m代表人,H代表房子,现在所有人要走到房子内,且一个房子只能容纳一个人(人和房子的数量相同),人每移动一步,需要花1美元,问所有人走到房子中的最 ...
- UVa 679 - Dropping Balls【二叉树】【思维题】
题目链接 题目大意: 小球从一棵所有叶子深度相同的二叉树的顶点开始向下落,树开始所有节点都为0.若小球落到节点为0的则往左落,否则向右落.并且小球会改变它经过的节点,0变1,1变0.给定树的深度D和球 ...