[SRM] 08 C

C-3 SRM 08

描述

给一个图,n 个点 m 条双向边,每条边有其长度。n 个点中有 k 个是特殊点,问任意两个特殊点的最短路是多少。

输入格式

第一行三个整数 n m k

第二行 k 个整数 ,为各个特殊点

接下来 m 行,每行三个整数 x y d,表示 x 到 y 有一条长度为 d 的边

输出格式

一个整数

样例输入

5 5 3
1 3 5
1 2 3
2 3 4
3 4 1
4 5 8
1 5 19

样例输出

7

数据范围与约定

  • 图为联通图

样例解释

样例中,1-3 的最短路为 7,3-5 的最短路为 9,1-5 的最短路为 16,因此答案为最小值 7

分析

想象所有的特殊点都在中央,而我们要求的就是:

那么当那根被称为“最短路”的橡皮筋只捆在特殊点上时,其中的最短的一部分就是我们要求的。

那么当我们在找最优解的过程就像把这根橡皮筋从无关点上一个点一个点的向特殊点收缩。

这听起来有些玄幻。

非常套路地,我们需要求出每个点的最短路(也就是多源最短路),但同时还要记录对应的源点

这样当我们拎着一条边的时候,如果这条边两端的端点不同,这条边对应的橡皮筋的部分长度为 A点的最短路+边长+B点最短路。

这样我们可以在求最短路的过程中顺便求解。

代码

 1 #include<cstdio>
 2 #include<queue>
 3 #include<iostream>
 4 #define maxn_E 5050500
 5 #define maxn_P 1010100
 6 #define INF 2147483647
 7 using namespace std;
 8 typedef pair<int,int> node;
 9 priority_queue<node,vector<node>,greater<node> > q;
10
11 struct edge{
12     int from,v,len;
13 }e[maxn_E];
14
15 int first[maxn_P],tot,ans = INF,n,m,k,a,b,c,dis[maxn_P],sou[maxn_P],spe[maxn_P];
16 bool book[maxn_P];
17
18 void insert(int u,int v,int len){
19     tot++;
20     e[tot].from = first[u];
21     e[tot].v = v;
22     e[tot].len = len;
23     first[u] = tot;
24 }
25
26 void dijkstra(){
27     for(int i = 1;i <= n;i++) dis[i] = INF;
28     for(int i = 1;i <= k;i++){
29         q.push(make_pair(0,spe[i]));
30         dis[spe[i]] = 0;
31         sou[spe[i]] = spe[i];
32     }
33
34     while(!q.empty()){
35         node tmp = q.top();
36         q.pop();
37
38         int p = tmp.second;
39
40         if(!book[p]){
41             book[p] = true;
42             for(int i = first[p];i;i = e[i].from){
43                 if(dis[p] != INF && dis[e[i].v] != INF && sou[p] != sou[e[i].v])
44                         ans = min(ans,dis[p]+e[i].len+dis[e[i].v]);
45                 if(dis[e[i].v] > dis[p]+e[i].len && !book[e[i].v]){
46                     if(sou[e[i].v] != sou[p])
47                         sou[e[i].v] = sou[p];
48                     dis[e[i].v] = dis[p]+e[i].len;
49                     q.push(make_pair(dis[e[i].v],e[i].v));
50 //                    if(sou[p] != sou[e[i].v])
51 //                        ans = min(ans,dis[p]+e[i].len+dis[e[i].v]);
52                 }
53             }
54         }
55     }
56 }
57
58 int main(){
59     scanf("%d%d%d",&n,&m,&k);
60
61     for(int i = 1;i <= k;i++) scanf("%d",&spe[i]);
62
63     for(int i = 1;i <= m;i++){
64         scanf("%d%d%d",&a,&b,&c);
65         insert(a,b,c);
66         insert(b,a,c);
67     }
68
69     dijkstra();
70
71 //    for(int i = 1;i <= n;i++){
72 //        printf("%d/%d ",dis[i],sou[i]);
73 //    }
74
75     printf("%d",ans);
76
77     return 0;
78 } 

推荐不看

时间: 2024-08-07 12:29:41

[SRM] 08 C的相关文章

汕头市队赛 SRM 08 B

B-3 SRM 08 描述 给长度为 n 的数列 A 和长度为 m 的数列 B,问有多少长度为 m 的数列 C 满足 输入格式 第一行俩整数 n 和 m 第二行 n 个整数 ,表示数列 A 第三行 m 个整数 ,表示数列 B 输出格式 一个整数,表示满足条件的数列 C 的个数模  后的值. 样例输入 1 5 3 1 5 2 4 7 7 9 6 样例输出 1 4 样例输入 2 4 2 7 7 7 7 3 4 样例输出 2 6 数据范围与约定 样例解释 第一个样例中,数列 C 可以为 (1, 3,

百度哈斯发卡号是减肥哈卡斯加分了卡斯

http://www.ebay.com/cln/ta_ya20/-/167521224015/2015.02.08 http://www.ebay.com/cln/p-m6466/-/167398283011/2015.02.08 http://www.ebay.com/cln/ta_ya20/-/167521242015/2015.02.08 http://www.ebay.com/cln/p-m6466/-/167398294011/2015.02.08 http://www.ebay.co

克同极用后管期果要议向中如极示听适VybVfesyhpR

社保划到税务征收,将大大提升社保费的征管效率.税务的征管能力是目前而言最强的,以后税务征收社保不是代收,属于本职了. 之前税局要把社保信息和交个税的工资比对起来有困难!现在好了,个税是自己的,社保也是自己的,比对困难?不存在的! 这一变革,会给那些不给员工上社保.不全额上社保的企业致命一击! 最新案例 前段时间的发改委关于限制特定严重失信人乘坐民航的一则意见--发改财金[2018]385号,其中还有税务总局的联合署名. http://weibo.com/20180408PP/2309279811

汕头市队赛 SRM 09 A 撕书

A 撕书I-3 SRM 09 背景&&描述 琉璃在撕书.     书总共有n页,都悬浮在数轴上,第i页的位置为,上面写着一个数字.     琉璃从右往左撕书.假如看到了第i页,就把在第i页左边,且与之距离<=的书都撕掉.(第i页本身不撕)     夜子为了尽量地保全魔法书,决定偷偷在琉璃开始撕之前,增加一页.增加的这一页必须在所有书页的右边,数字随意.     夜子想知道,最少会有多少页书被撕毁. 输入格式 第一行一个整数n,表示书页数. 接下来n行,第i行的俩整数分别为和. 输出格

Bootstrap 3.2.0 源码试读 2014/08/09

第一部分 normalize.css 104至110行 code,    /* 编辑代码 */ kbd,    /* 键盘输入的文本 */ pre, samp {    /* 范例,sample的简写 */   font-family: monospace, monospace;    /* 这个地方应该是写错了,第二字体应该是serif */   font-size: 1em; } 设置字体的大小为1em,字体为monospace. 111至119行 button, input, optgro

笔试算法题(08):输出倒数第K个节点

出题:输入一个单向链表,要求输出链表中倒数第K个节点 分析:利用等差指针,指针A先行K步,然后指针B从链表头与A同步前进,当A到达链表尾时B指向的节点就是倒数第K个节点: 解题: 1 struct Node { 2 int v; 3 Node *next; 4 }; 5 Node* FindLastKth(Node *head, int k) { 6 if(head==NULL) { 7 printf("\nhead is NULL\n"); 8 exit(0); 9 } 10 Nod

android插件化-apkplug中OSGI服务基本原理-08

我们提供 apkplug 下OSGI使用demo 源码托管地址为 http://git.oschina.net/plug/OSGIService 一 OSGI与android Service 异同点 OSGI服务与android Service概念差不多也是Service ,Client 关系. android Service接口  --service.AIDL OSGI接口                --java interface 所以android 进程间通信Service只能传递序列

2014年4月23日 10:22:08

step 1 : 做tcp网络编程,要解析一批批的数据,可是数据是通过Socket连接的InputStream一次次读取的,读取到的不是需要转换的对象,而是要直接根据字节流和协议来生成自己的数据对象. 按照之前的编程思维,总是请求然后响应,当然Socket也是请求和响应,不过与单纯的请求响应是不同的. 这里Socket连接往往是要保持住的,也就是长连接,然后设置一个缓冲区,网络流不断的追加到缓冲区.然后后台去解析缓冲区的字节流. http://cuisuqiang.iteye.com/blog/

java进阶08 GUI图形界面

图形化用户界面(GUI) 简而言之,就是可视化编程. 要想实现可视化界面(窗口),需要用到JFrame类. package Frame; public class JFrame1 { public static void main(String[] args){ UI ui=new UI(); } } 先建一个主函数,而主函数中的操作只有一句代码.这样做,既能直观又方便后期修改. 接下来是UI类的实现 package Frame; import javax.swing.JFrame; publi