HDU 6166 Senior Pan(多校第九场 二进制分组最短路)
题意:给出n个点和m条有向边(有向边!!!!我还以为是无向查了半天),然后给出K个点,问这k个点中最近的两点的距离
思路:比赛时以为有询问,就直接丢了,然后这题感觉思路很棒,加入把所有点分成起点和终点两部分,然后加个S点和T点与他们
的距离为0,然后跑最短路就可以了,但是这样有可能最近的两个点都在起点或者都在终点,那么就不一定是最短的,所以就有个二进制分组。
考虑每个点的编号的二进制表示,那么对于任何两个点,他们至少有一位二进制不同,那么我们通过枚举二进制的位,当前位为1的作为起点集合,
当前位为2的作为终点集合,通过这样分组,我们就可以确定至少有一次分组任意两点分别在起点和终点。
复杂度O(20*nlogm)
代码:
/** @xigua */
#include <cstdio>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <cstring>
#include <queue>
#include <set>
#include <string>
#include <map>
#include <climits>
#define PI acos(-1)
using namespace std;
typedef long long ll;
typedef double db;
const int maxn = 1e5 + 5;
const int mod = 1e9 + 7;
const int INF = 1e8 + 5;
const ll inf = 1e15 + 5;
const db eps = 1e-5;
int cnt, head[maxn]; ll dis[maxn];
struct Edge {
int v, next; ll w; //记住这里改顺序下面push进队一定要改!
bool operator < (const Edge &rhs) const {
return w > rhs.w;
}
} e[maxn<<2]; void add(int u, int v, int co) {
e[cnt].v = v;
e[cnt].w = co;
e[cnt].next = head[u];
head[u] = cnt++;
} void init() {
cnt = 0;
memset(head, -1, sizeof(head));
} void dij(int s, int len) {
priority_queue<Edge> pq;
for (int i = 1; i <= len; i++)
dis[i] = inf;
bool vis[maxn] = {0};
dis[s] = 0;
pq.push((Edge){s, 0, 0});
while (!pq.empty()) {
Edge tmp = pq.top(); pq.pop();
if (vis[tmp.v]) continue;
vis[tmp.v] = 1;
for (int i = head[tmp.v]; ~i; i = e[i].next) {
Edge u = e[i];
if (dis[u.v] > dis[tmp.v] + u.w) {
dis[u.v] = dis[tmp.v] + u.w;
pq.push((Edge){u.v, 0, dis[u.v]});
}
}
}
}
int a[maxn];
int u[maxn], v[maxn], w[maxn]; void solve() {
int n, m; cin >> n >> m;
for (int i = 1; i <= m; i++) {
scanf("%d%d%d", u + i, v + i, w + i);
}
int k; cin >> k;
for (int i = 1; i <= k; i++) {
scanf("%d", a + i);
}
ll ans = inf;
for (int i = 0; i < 20; i++) {
init();
for (int j = 1; j <= m; j++) {
add(u[j], v[j], w[j]);
// add(v[j], u[j], w[j]);
}
for (int j = 1; j <= k; j++) {
if ((1<<i) & j) {
add(0, a[j], 0);
}
else {
add(a[j], n+1, 0);
}
}
dij(0, n + 10);
ans = min(ans, dis[n+1]);
init();
for (int j = 1; j <= m; j++) {
add(u[j], v[j], w[j]);
// add(v[j], u[j], w[j]);
}
for (int j = 1; j <= k; j++) {
if (((1<<i) & j) == 0) {
add(0, a[j], 0);
}
else {
add(a[j], n+1, 0);
}
}
dij(0, n + 10);
ans = min(ans, dis[n+1]);
}
cout << ans << endl;
} int main() {
int t = 1, cas = 1;
// freopen("in.txt", "r", stdin);
// freopen("in.txt", "w", stdout);
// init();
scanf("%d", &t);
while(t--) {
printf("Case #%d: ", cas++);
solve();
}
return 0;
}
HDU 6166 Senior Pan(多校第九场 二进制分组最短路)的更多相关文章
- hdu 6166 Senior Pan
http://acm.hdu.edu.cn/showproblem.php?pid=6166 题意: 给出一张无向图,给定k个特殊点 求这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 ...
- 2017多校第9场 HDU 6166 Senior Pan 堆优化Dij
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6166 题意:给你一个有向图,然后给你k个点,求其中一个点到另一个点的距离的最小值. 解法:枚举二进制位 ...
- HDU 6166 Senior Pan(k点中最小两点间距离)题解
题意:n个点,m条有向边,指定k个点,问你其中最近的两点距离为多少 思路:这题的思路很巧妙,如果我们直接枚举两点做最短路那就要做C(k,2)次.但是我们换个思路,我们把k个点按照二进制每一位的0和1分 ...
- HDU 6166 Senior Pan(二进制分组+最短路)
题意 给出一个\(n\)个点\(m\)条边的有向图\((n,m<=100000)\),从中选择\(k\)个点\((k<=n)\),问这k个点两两之间的最短路最小值是多少? 思路 直接的想法 ...
- 2018 Multi-University Training Contest 9 杭电多校第九场 (有坑待补)
咕咕咕了太久 多校博客直接从第三场跳到了第九场orz 见谅见谅(会补的!) 明明最后看下来是dp场 但是硬生生被我们做成了组合数专场…… 听说jls把我们用组合数做的题都用dp来了遍 这里只放了用组 ...
- hdu 6169 Senior PanⅡ Miller_Rabin素数测试+容斥
Senior PanⅡ Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others) Pr ...
随机推荐
- android系统的源代码获取(亲测可用)
1.在线阅读各版本源代码: http://androidxref.com/ 2.下载到本地: http://blog.csdn.net/yin1031468524/article/details/55 ...
- 精通BitmapData
一.构造方法: var bmd:BitmapData=new BitmapData(200,100,true,0xffff0000); 参数说明: 1.宽 2.高 3.是否使用32位填充位图(包括al ...
- JQuery学习笔记(二)JQuery方法
jQuery 提供一系列与 DOM 相关的方法,便于访问和操作元素和属性 Query 文档操作方法 这些方法对于 XML 文档和 HTML 文档均是适用的,除了:html(). 方法 描述 addCl ...
- 模板 - 洲阁筛 + min25筛
好像在某些情况下杜教筛会遇到瓶颈,先看着.暑假学一些和队友交错的知识的同时开这个大坑.
- POJ2406【KMP-next数组】
关于next的解释原文:点点点 //#include <bits/stdc++.h> #include<cstdio> #include<string.h> #in ...
- Lightoj 1008【规律】
25 24 23 22 21 10 11 12 13 20 9 8 7 14 19 2 3 6 15 18 1 4 5 16 17 然后把这个转化成: 17 18 19 20 21 10 11 12 ...
- PL/SQL基础知识
Oracle之PL/SQL学习笔记 自己在学习Oracle是做的笔记及实验代码记录,内容挺全的,也挺详细,发篇博文分享给需要的朋友,共有1w多字的学习笔记吧.是以前做的,一直在压箱底,今天拿出来整理了 ...
- (十一)SpringBoot导出excel文件
一:添加POI依赖 <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-oox ...
- iOS蓝牙连接流程介绍-1
蓝牙连接流程介绍 1.1-程序员找女朋友流程介绍 0.程序员找女朋友参与者 1.你 2.受害者(女性同胞) (1)她的性格1 性格的特点 (2)她的性格2 分析性格的特点 1.寻找女性 寻尽身边一 ...
- nginx,tomcat,apache三者分别用来做什么,有何区别
1. Nginx和tomcat的区别 nginx常用做静态内容服务和代理服务器,直接外来请求转发给后面的应用服务器(tomcat,Django等),tomcat更多用来做一个应用容器,让java we ...