汕头市队赛 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
这道题对我来说有点难啊 想了半天只会跑k-1次最短路 最后在大爷的帮助下还是写出来了 果然自己还是过于蒟蒻QAQ
这道题呢 我的写法是 将所有的关键点以0作为初始距离 扔进优先队列里面 跑一遍Dijkstra
记录每个点最近的关键点以及到关键点的距离(dis)
最后枚举边 如果两端的点的最近关键点不一样就更新一波答案
下面证明写法的正确性
我们在跑最短路的时候顺便记录一下每个点是从哪个点扩展来的
首先显然答案不可能比真实的答案偏小 所以证明如果答案存在 则一定能找到
设一个最优解a——b——c——d,a,d为关键点,
1. dis(a,b)<=dis(a,d)/2
2. dis(c,d)<=dis(a,d)/2
(证明b,c之间有边)
如果因为等距离的问题 b,c 的最近关键点不是 a,d, 那么只要 b,c 的最近关键点不同,仍可得到答案
如果 b,c 的最近关键点相同 设这个点为x,那么令 x!=a
那么 dis(a,x)=dis(a,b)+dis(b,x)<=dis(a,b)+dis(b,c)+dis(c,x)=dis(a,b)+dis(b,c)+dis(c,d)
可见 a——b——x 不比 a——b——c——d 差,
如果两个都是最优解 那么由于dis(a,b)==dis(b,x)==dis(a,d)/2
设 a到b路径上最靠近b的点为 e 则dis(e,a)<dus(a,b)=dis(b,x)
所以e的最近关键点不会是x , 那么 (e的最近关键点)——e——b————x这条路同上面两条一样是另一个最优解 且能由e-b更新
证毕
然后就贴一波代码咯 2333
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int M=1e5+,inf=1e9+;
int read(){
int ans=,f=,c=getchar();
while(c<''||c>''){if(c=='-') f=-; c=getchar();}
while(c>=''&&c<=''){ans=ans*+(c-''); c=getchar();}
return ans*f;
}
int n,m,k,p[M],dis[M],blong[M];
int cnt,first[M],ans=inf,h[M];
struct note{int to,from,next,w;}e[*M];
void ins(int a,int b,int w){cnt++; e[cnt].to=b; e[cnt].from=a; e[cnt].next=first[a]; e[cnt].w=w; first[a]=cnt;}
void insert(int a,int b,int w){ins(a,b,w); ins(b,a,w);}
struct node{
int d,pos;
bool operator <(const node& x)const{return x.d<d;}
};
priority_queue<node>q;
void dj(){
for(int i=;i<=n;i++) dis[i]=inf;
for(int i=;i<=k;i++){
int now=p[i];
blong[now]=now; dis[now]=;
q.push((node){,now});
}
while(!q.empty()){
node y=q.top(); q.pop();
int x=y.pos;
if(y.d>dis[x]) continue;
for(int i=first[x];i;i=e[i].next){
int now=e[i].to;
if(dis[now]>dis[x]+e[i].w){
dis[now]=dis[x]+e[i].w;
blong[now]=blong[x];
q.push((node){dis[now],now});
}
}
}
}
int main()
{
int x,y,w;
n=read(); m=read(); k=read();
for(int i=;i<=k;i++) p[i]=read(),h[p[i]]=;
for(int i=;i<=m;i++){
x=read(); y=read(); w=read();
insert(x,y,w); if(h[x]&&h[y]) ans=min(ans,w);
}//printf("%d\n",ans);
dj();
for(int i=;i<=cnt;i+=)
if((!h[e[i].to]||!h[e[i].from])&&blong[e[i].from]!=blong[e[i].to])
ans=min(ans,dis[e[i].from]+dis[e[i].to]+e[i].w);
printf("%d\n",ans);
return ;
}
汕头市队赛 SRM 08 C的更多相关文章
- 汕头市队赛 SRM 08 B
B-3 SRM 08 描述 给长度为 n 的数列 A 和长度为 m 的数列 B,问有多少长度为 m 的数列 C 满足 输入格式 第一行俩整数 n 和 m 第二行 n 个整数 ,表示数列 A 第三行 m ...
- 汕头市队赛 SRM 08 A
比赛没参加 所以回来补题咯 A还是自己YY出来了的 可惜比赛没有打 描述 给一个 01 串设为其 S,询问是否存在只出现两次的 01 串 T. 这里的出现定义为存在一串下标 ,满足 且 . 输入格式 ...
- 汕头市队赛 SRM 07 D 天才麻将少女kpm
这道题放了很久还是回来补了 D 天才麻将少女KPM SRM 07 背景&&描述 天才麻将少女KPM立志要在日麻界闯出一番名堂. KPM上周叒打了n场麻将,但她这次又没控分,而且 ...
- 汕头市队赛SRM 20 T2不净的圣杯
不净的圣杯 SRM 20 背景 作为一张BUG级别的卡,官方打算把它修改得人畜无害一些…… 虽然名字还没想好,但是能力大概是对敌方所有单位造成d点伤害,d为自己牌组中所有卡的编号的最大公约数.这无疑是 ...
- 汕头市队赛 SRM 07 B 好玩的麻将
B 好玩的麻将 SRM 07 背景&&描述 天才麻将少女KPM立志要在日麻界闯出一番名堂. KPM上周又打了n场麻将,又控了分使得自己的排名是1..n的一个排列. 但她 ...
- 汕头市队赛 SRM 06 C 秀恩爱
C 秀恩爱 SRM 06 背景&&描述 KPM坐在直升机上俯瞰小渔村景象. 渔村可看作二维平面,密密麻麻地到处都是单身狗,KPM当前所在坐标为(sx,s ...
- 汕头市队赛 SRM 06 A 撕书
A 撕书 SRM 06 背景&&描述 游行寺汀正在杀书. 书总共有n页,每页都可以看作是一个小写英文字母,所以我们可以把书看成长度为n的字符串s. 琉璃 ...
- 汕头市队赛 SRM 06 B 起伏的排名
B 起伏的排名 SRM 06 背景&&描述 天才麻将少女KPM立志要在日麻界闯出一番名堂. 在上个星期她打了n场麻将,每场麻将都有n名玩家.KPM自然记得自己的n次排名. ...
- 汕头市队赛 SRM 07 A 你的麻将会排序吗
A 你的麻将会排序吗 SRM 07 曾经有过一些沉迷日麻的小孩纸,后来呀,他们都去寻找自己的世界了. kpm也是这样的小孩纸.他想有一只自动整理牌的机器.当麻将以给定的顺序进入机器时,通过机器的运转, ...
随机推荐
- Oauth2.0协议 http://www.php20.com/forum.php?mod=viewthread&tid=28 (出处: 码农之家)
概要 OAuth2.0是OAuth协议的下一版本,但不向后兼容OAuth 1.0即完全废止了OAuth1.0. OAuth 2.0关注客户端开发者的简易性.要么通过组织在资源拥有者和HTTP服 ...
- Apache安装之后,在浏览器输入ip无法访问
博主本来在linux下面配置安装了apache,然后用浏览器输入ip却无法访问 就一直在想是不是dns无法解析的问题,最后才发现原来是防火墙的原因, 在linux下面 service iptables ...
- c语言printf()输出格式大全(转载)
1.转换说明符 %a(%A) 浮点数.十六进制数字和p-(P-)记数法(C99) %c 字符 %d 有符号十进制整 ...
- 多个".h"文件中声明及定义 全局变量和函数
一.".h"文件必须以如下格式书写 例:文件<CZ_efg_hi.h"> ------------文件内容----------- #ifndef CZ_Efg ...
- CC3200在AP模式的TCP sock作为客户端连接时返回SL_ECONNREFUSED(-111) Connection refused
1. CC3200处于AP模式(电脑无线连接CC3200的WIFI信号),开启一个TCP socket,这个socket作为TCP客户端去连接TCP服务器端 struct sockaddr_in ad ...
- python里面list()函数
1. list() 方法用于将元组转换为列表. 元组与列表是非常类似的,区别在于元组的元素值不能修改,元组是放在括号中,列表是放于方括号中. 2. python里面的变量不用提前声明.
- 云计算之路-阿里云上:OCS问题的进展以及11:30-11:50遇到的问题
(上图是今天出问题期间Web服务器性能监控图,紫色表示的是Request Execution Time) 昨天我们发布了一篇博客分享了我们这两天遇到的OCS(开放缓存服务)问题,详见云计算之路-阿里云 ...
- 《Cracking the Coding Interview》——第3章:栈和队列——题目5
2014-03-18 05:33 题目:用两个栈来实现一个队列. 解法:栈是反的,队列是正的,反了再反就正过来了.所以,请看代码.操作中时间复杂度有O(1)的,有O(n)的,但均摊下来时间符合O(1) ...
- 通过slf4j/log4j的MDC/NDC 实现日志追踪
在分布式系统或者较为复杂的系统中,我们希望可以看到一个客户请求的处理过程所涉及到的所有子系统\模块的处理日志. 由于slf4j/log4j基本是日志记录的标准组件,所以slf4j/log4j成为了我的 ...
- python 由递归的dict构建树的画图代码
createPlot(mytree)方法实现. 其中myTree是一个字典,调用retrieveTree(0)可以获得一个字典的样式. Last login: Thu Feb 23 19:07:53 ...