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 ...
随机推荐
- Nestjs OpenAPI(Swagger)
官方文档 用来描述api
- 萌新 学习 vuex
vuex官网文档 https://vuex.vuejs.org/zh-cn/ 注: Mutation事件使用commit触发, Actions事件使用dispatch触发 安装 npm install ...
- Git 与 SVN 命令学习笔记
一:Git git config --global user.name "you name" #设置用户名git config --global user.email &quo ...
- ubuntu下安装php扩展
参考原文地址:http://www.php.cn/php-weizijiaocheng-341528.html 发现在mac上好像不太行,然后按照下面的可以,写下来与大家分享 利用ubuntu的软件包 ...
- 四、XML语言学习(1)
XML语言 1.XML是什么?XML是指可扩展标记语言XML是指可扩展标记语言(eXtensible Markup Language),它是一种标记语言,很类似HTML.它被设计的宗旨是传输数据,而非 ...
- 数组copy
数组copy(推荐用法) System.arraycopy的用法 int[] src = {1,3,5,7,9,11,13,15,17}; int[] dest = {2,4,6,8,10,12,14 ...
- C# 如何使用长度来切分字符串
参考网址:https://blog.csdn.net/yenange/article/details/39637211 using System; using System.Collections.G ...
- jmeter录制https请求
工具:Jmeter4.0 + Java1.8 需求:对某https网站进行 登录-修改信息-退出 场景的压力测试 方法:使用Apache JMeter HTTP(S) Test Script Reco ...
- git 如何删除已经add的文件
git rm --cached "文件" 参考: https://blog.csdn.net/kiss_the_sky/article/details/77921206
- phpcms网页替换验证码功能 及 搜索功能
在使用phpcms替换网页的时候,除了正常的替换栏目.内容页等,其他的什么验证码啦,提交表单了,搜索功能了,这些在替换的时候可能会对一些默认文件有一些小小 的改变 下面就是自己在失败中成功的过程,最后 ...