HDU 6166 Senior Pan(k点中最小两点间距离)题解
题意: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点中最小两点间距离)题解的更多相关文章
- HDU 6166 Senior Pan (最短路变形)
题目链接 Problem Description Senior Pan fails in his discrete math exam again. So he asks Master ZKC to ...
- HDU 6166.Senior Pan()-最短路(Dijkstra添加超源点、超汇点)+二进制划分集合 (2017 Multi-University Training Contest - Team 9 1006)
学长好久之前讲的,本来好久好久之前就要写题解的,一直都没写,懒死_(:з」∠)_ Senior Pan Time Limit: 12000/6000 MS (Java/Others) Memor ...
- HDU 6166 Senior Pan 二进制分组 + 迪杰斯特拉算法
Senior Pan Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Probl ...
- hdu 6166 Senior Pan
http://acm.hdu.edu.cn/showproblem.php?pid=6166 题意: 给出一张无向图,给定k个特殊点 求这k个特殊点两两之间的最短路 二进制分组 枚举一位二进制位 这一 ...
- 2017多校第9场 HDU 6166 Senior Pan 堆优化Dij
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6166 题意:给你一个有向图,然后给你k个点,求其中一个点到另一个点的距离的最小值. 解法:枚举二进制位 ...
- HDU 6166 Senior Pan(多校第九场 二进制分组最短路)
题意:给出n个点和m条有向边(有向边!!!!我还以为是无向查了半天),然后给出K个点,问这k个点中最近的两点的距离 思路:比赛时以为有询问,就直接丢了,然后这题感觉思路很棒,加入把所有点分成起点和终点 ...
- HDU 6166 Senior Pan(二进制分组+最短路)
题意 给出一个\(n\)个点\(m\)条边的有向图\((n,m<=100000)\),从中选择\(k\)个点\((k<=n)\),问这k个点两两之间的最短路最小值是多少? 思路 直接的想法 ...
- hdu 6169 Senior PanⅡ Miller_Rabin素数测试+容斥
Senior PanⅡ Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others) Pr ...
- 2017多校第9场 HDU 6169 Senior PanⅡ 数论,DP,爆搜
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6169 题意:给了区间L,R,求[L,R]区间所有满足其最小质数因子为k的数的和. 解法: 我看了这篇b ...
随机推荐
- properties文件读取工具类
项目中防止硬编码,经常会将一些与业务相关的数据存在properties文件中,根据不同的key加载不同的数据,所以就会有读取properties文件的东西,这篇文章仅为了以后copy方便写的. 1.添 ...
- python的time
有时候需要获取并格式化输出把当前时间,需要用到datetime的strftime方法 >>from datetime import datetime >>datetime.no ...
- Linux命令 umask
umask: 文件预设权限 指定当前用户在创建文件或目录时的权限默认值. $ umask0002$ umask -Su=rwx,g=rwx,o=rx 创建文件时,预设没有x 权限,即只有rw 权限,最 ...
- 浅谈Vue 项目性能优化 经验
我优化公司的项目总结的几点: 1.先查看引入的图片大小,如果太大了,可以压缩,压缩路径:https://zhitu.isux.us/ 2.代码包优化, 待下项目开发完成.进行打包源码上线环节,需要对项 ...
- day15,内置函数一
1,复习,如何从生成器里面取值,next(每次取一个值),send(不可以用在第一个,取下一个的时候,给上一个地方传一个值),for(没有break会一直取,直到取完),强制转换(会一次性把数据加载到 ...
- odoo配置文件内容详解
odoo常用openerp-server.conf配置参数详解 参数 说明 用法 addons_path addons模块的查找路径,多个路径用逗号分隔 addons_path = E:\GreenO ...
- EXT的bug 布局border 和 grid的cellediting
首先 我要的布局是上下两块,并且高度和按自己的喜欢可调节,所以我采用的是border的布局, 上下两块,都放grid列表,上面一块不可编辑,下面这块可编辑,如图 在编辑第二块的时候会出现这个现象 图一 ...
- 7.0-uC/OS-III中断管理
1.CPU的中断处理 理器通常有多个中断源. 例如, UART中断. DMA中断. ADC中断.定时器中断等. 2.中断器件标志中断处理器,然后中断处理器将优先级最高的中断提交给CPU. 现在的中断控 ...
- MongoDB 备份(mongodump)与恢复(mongorestore)
MongoDB 备份(mongodump)与恢复(mongorestore) 备份:使用mongodump命令导出所有数据库到指定目录 参数说明: --host:MongoDB所在服务器IP. -- ...
- 漫画HDFS工作原理(转)
转自:http://blog.csdn.net/netcoder/article/details/7442779?locationNum=2 对漫画内容更好的解读,可参考: http://www.we ...