题意:n个点,m条有向边,指定k个点,问你其中最近的两点距离为多少

思路:这题的思路很巧妙,如果我们直接枚举两点做最短路那就要做C(k,2)次。但是我们换个思路,我们把k个点按照二进制每一位的0和1分类logn次,然后做集合最短距离。因为任意两个不等的数,总有一位不一样,所以每个点都有机会和其他点在不同集合。那么这样就花了logn次枚举了所有情况。集合最短距离可以指定一个超级源点和超级汇点,然后做两点最短路。

代码:

#include<cmath>
#include<set>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include <iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = + ;
const ull seed = ;
const int INF = 0x3f3f3f3f;
const int MOD = ;
struct Edge{
int to, w, next;
}edge[maxn * ];
struct node{
int v, w;
node(int _v = , int _w = ): v(_v), w(_w){}
bool operator < (const node r) const{
return w > r.w;
}
};
int head[maxn], tot;
void addEdge(int u, int v, int w){
edge[tot].w = w;
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
}
int n, m, k;
int dis[maxn], q[maxn];
bool vis[maxn];
int dij(int s, int e){
memset(vis, false, sizeof(vis));
memset(dis, INF, sizeof(dis));
priority_queue<node> Q;
while(!Q.empty()) Q.pop();
dis[s] = ;
Q.push(node(s, ));
node tmp;
while(!Q.empty()){
tmp = Q.top();
Q.pop();
int u = tmp.v;
if(vis[u]) continue;
vis[u] = true;
for(int i = head[u]; i != -; i = edge[i].next){
int v = edge[i].to;
if(!vis[v] && dis[v] > dis[u] + edge[i].w){
dis[v] = dis[u] + edge[i].w;
Q.push(node(v, dis[v]));
}
}
}
return dis[e];
}
void init(){
memset(head, -, sizeof(head));
tot = ;
}
int a[maxn], b[maxn], w[maxn];
int main(){
int T, ca = ;
scanf("%d", &T);
while(T--){
scanf("%d%d", &n, &m);
for(int i = ; i <= m; i++){
scanf("%d%d%d", &a[i], &b[i], &w[i]);
}
scanf("%d", &k);
for(int i = ; i <= k; i++){
scanf("%d", &q[i]);
}
int ans = INF, p = ;
while(n >> p){
init();
for(int i = ; i <= m; i++)
addEdge(a[i], b[i], w[i]);
for(int i = ; i <= k; i++){
if((q[i] >> p) & ){
addEdge(, q[i], );
}
else{
addEdge(q[i], n + , );
}
}
ans = min(ans, dij(, n + ));
init();
for(int i = ; i <= m; i++)
addEdge(a[i], b[i], w[i]);
for(int i = ; i <= k; i++){
if((q[i] >> p) & ){
addEdge(q[i], , );
}
else{
addEdge(n + , q[i], );
}
}
ans = min(ans, dij(n + , ));
p++;
}
printf("Case #%d: %d\n", ca++, ans);
}
return ;
}

HDU 6166 Senior Pan(k点中最小两点间距离)题解的更多相关文章

  1. HDU 6166 Senior Pan (最短路变形)

    题目链接 Problem Description Senior Pan fails in his discrete math exam again. So he asks Master ZKC to ...

  2. HDU 6166.Senior Pan()-最短路(Dijkstra添加超源点、超汇点)+二进制划分集合 (2017 Multi-University Training Contest - Team 9 1006)

    学长好久之前讲的,本来好久好久之前就要写题解的,一直都没写,懒死_(:з」∠)_ Senior Pan Time Limit: 12000/6000 MS (Java/Others)    Memor ...

  3. HDU 6166 Senior Pan 二进制分组 + 迪杰斯特拉算法

    Senior Pan Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Probl ...

  4. hdu 6166 Senior Pan

    http://acm.hdu.edu.cn/showproblem.php?pid=6166 题意: 给出一张无向图,给定k个特殊点 求这k个特殊点两两之间的最短路 二进制分组 枚举一位二进制位 这一 ...

  5. 2017多校第9场 HDU 6166 Senior Pan 堆优化Dij

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6166 题意:给你一个有向图,然后给你k个点,求其中一个点到另一个点的距离的最小值. 解法:枚举二进制位 ...

  6. HDU 6166 Senior Pan(多校第九场 二进制分组最短路)

    题意:给出n个点和m条有向边(有向边!!!!我还以为是无向查了半天),然后给出K个点,问这k个点中最近的两点的距离 思路:比赛时以为有询问,就直接丢了,然后这题感觉思路很棒,加入把所有点分成起点和终点 ...

  7. HDU 6166 Senior Pan(二进制分组+最短路)

    题意 给出一个\(n\)个点\(m\)条边的有向图\((n,m<=100000)\),从中选择\(k\)个点\((k<=n)\),问这k个点两两之间的最短路最小值是多少? 思路 直接的想法 ...

  8. hdu 6169 Senior PanⅡ Miller_Rabin素数测试+容斥

    Senior PanⅡ Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others) Pr ...

  9. 2017多校第9场 HDU 6169 Senior PanⅡ 数论,DP,爆搜

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6169 题意:给了区间L,R,求[L,R]区间所有满足其最小质数因子为k的数的和. 解法: 我看了这篇b ...

随机推荐

  1. 牛客练习赛36B

    唔在cf上做过,A题也做过,神仙说D题也是原题 这个题就是dp了.然后数组滚动一下,很显然能住遇到  i 只与 i-1 有关,所以还是挺好滚的. dp[i][j][k]表示到第I 天一共工作了J天连续 ...

  2. css 获取从第n个开始,之后的所有元素

    <div id="box"> <div></div> <div>等待获取</div> <div>等待获取&l ...

  3. js模拟发送 FormData数据

    后台express需要connect-multiparty模块接收formData的数据类型 class ourFormData { constructor(data, rs) { return ne ...

  4. python全栈开发 * 18 面向对象知识点汇总 * 180530

    18 面向对象初识1class person: level="高级动物" mind="有思想" def __init__(self,name,age,gent, ...

  5. CentOS 7.6 安装Oracle 12c

    下载地址: http://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.html https://www ...

  6. ADG日志传输方式参数log_archive_dest_n详解

    主库的日志发送是由log_archive_dest_n参数设置(注意:同时还有一个和它相对应的开关参数log_archive_dest_state_n,用于指定该参数是否有效),下面简单介绍下该参数各 ...

  7. 【转载】MDK环境下让STM32用上FreeRTOS v8.1.2和FreeRTOS+Trace v2.6.0全过程

    [转载]https://www.amobbs.com/thread-5601460-1-2.html?_dsign=6a59067b   本人选择使用FreeRTOS的最大原因就是想使用FreeRTO ...

  8. java框架之SpringCloud(4)-Ribbon&Feign负载均衡

    在上一章节已经学习了 Eureka 的使用,SpringCloud 也提供了基于 Eureka 负载均衡的两种方案:Ribbon 和 Feign. Ribbon负载均衡 介绍 SpringCloud ...

  9. Linux常用总结

    CentOS 7.0中一个最主要的改变,就是切换到了systemd.它用于替代红帽企业版Linux前任版本中的SysV和Upstart,对系统和服务进行管理.systemd兼容SysV和Linux标准 ...

  10. 关于EasyUI查询功能的二级联动

    EasyUI 二级联动 data-options="multiple:true" 属性可实现对于车牌号的多选.