时间限制: 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的更多相关文章

  1. 洛谷 P3905 道路重建 题解

    P3905 道路重建 题目描述 从前,在一个王国中,在\(n\)个城市间有\(m\)条道路连接,而且任意两个城市之间至多有一条道路直接相连.在经过一次严重的战争之后,有\(d\)条道路被破坏了.国王想 ...

  2. P1359 租用游艇 && P3905 道路重建 ------Floyd算法

    P1359 租用游艇   原题链接https://www.luogu.org/problemnew/show/P1359 P3905 道路重建   原题链接https://www.luogu.org/ ...

  3. P3905 道路重建

    P3905 道路重建我一开始想错了,我的是类似kruskal,把毁坏的边从小到大加,并且判断联通性.但是这有一个问题,你可能会多加,就是这条边没用,但是它比较小,你也加上了.居然还有10分,数据也是水 ...

  4. 洛谷——P3905 道路重建

    P3905 道路重建 题目描述 从前,在一个王国中,在n个城市间有m条道路连接,而且任意两个城市之间至多有一条道路直接相连.在经过一次严重的战争之后,有d条道路被破坏了.国王想要修复国家的道路系统,现 ...

  5. 洛谷 P3905 道路重建

    题目描述 从前,在一个王国中,在n个城市间有m条道路连接,而且任意两个城市之间至多有一条道路直接相连.在经过一次严重的战争之后,有d条道路被破坏了.国王想要修复国家的道路系统,现在有两个重要城市A和B ...

  6. [JZOJ 5465] [NOIP2017提高A组冲刺11.9] 道路重建 解题报告 (e-dcc+树的直径)

    题目链接: http://172.16.0.132/senior/#main/show/5465 题目: 小X所居住的X国共有n个城市,有m条无向道路将其连接.作为一个统一的国家,X 城的任意两个城市 ...

  7. 洛谷P3905 道路重建

    题目:https://www.luogu.org/problemnew/show/P3905 分析: 此题是显然的最短路算法,只是看到一起删掉的一堆边感到十分棘手,而且还要求出的是最短添加边的总长度 ...

  8. SPFA--P3905 道路重建

    题目描述 从前,在一个王国中,在n个城市间有m条道路连接,而且任意两个城市之间至多有一条道路直接相连.在经过一次严重的战争之后,有d条道路被破坏了.国王想要修复国家的道路系统,现在有两个重要城市A和B ...

  9. 【洛谷P1272】道路重建

    题目大意:给定一个 N 个节点的树,求至少剪掉多少条边才能使得从树中分离出一个大小为 M 的子树. 题解:考虑树形 dp,定义 \(dp[u][i][t]\) 为以 u 为根节点与前 i 个子节点构成 ...

随机推荐

  1. 错误 java.lang.ClassCastException: com.xx cannot be cast to ResourceBundle

    出现错误: java.lang.ClassCastException: com.xxx cannot be cast to ResourceBundle 百度搜索错误,没有结果.谷歌搜索:http:/ ...

  2. 秒懂C#通过Emit动态生成代码

    首先需要声明一个程序集名称, 1 // specify a new assembly name 2 var assemblyName = new AssemblyName("Kitty&qu ...

  3. Python学习(十七)—— 数据库(二)

    转载自http://www.cnblogs.com/linhaifeng/articles/7356064.html 一. 数据库管理软件的由来 基于我们之前所学,数据要想永久保存,都是保存于文件中, ...

  4. fillder--信息面板展示serverIP

    1.Ctrl+R打开面板 2.如上图的位置,加上一句后,重启Fillder即可 FiddlerObject.UI.lvSessions.AddBoundColumn(, "X-HostIP& ...

  5. UOJ#33. 【UR #2】树上GCD 点分治 莫比乌斯反演

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ33.html 题解 首先我们把问题转化成处理一个数组 ans ,其中 ans[i] 表示 d(u,a) 和 ...

  6. 【转】Java开发必须要知道的知识体系

    Java Java是一门超高人气编程语言,拥有跨平台.面向对象.泛型编程等特性.在TIOBE编程语言排行榜中,连续夺得第一宝座,而且国内各大知名互联网公司,后端开发首选语言:非Java莫属.今天只是梳 ...

  7. springboot(@Service,@Mapper)注解失效导致无法注入service和mapper

    给我来灵感的博客:感谢:http://blog.51cto.com/xingej/2053297?utm_source=oschina-app 因为使用了注解的类在使用时是通过new出来的,导致注解注 ...

  8. Count the string kmp

    问题描述众所周知,aekdycoin擅长字符串问题和数论问题.当给定一个字符串s时,我们可以写下该字符串的所有非空前缀.例如:S:“ABAB”前缀是:“A”.“AB”.“ABA”.“ABAB”对于每个 ...

  9. 爬虫之 beautifusoup4

    1. 使用方法 2.解析器 3. 详细用法 4. find_all方法 5. 遍历文档树

  10. Zookeeper三个监听案例

    一.监听某一节点内容 /** * @author: PrincessHug * @date: 2019/2/25, 14:28 * @Blog: https://www.cnblogs.com/Hel ...