题目原文:

企鹅豆豆即将要去考长跑了,但是作为一只企鹅,长跑自然比不过鸵鸟和鸡。为了公平起见,教练告诉豆豆,他可以从 K 个指定地点中选择两个不同的地点分别作为起点和终点来考试.考试地图是一个由 N 个点 M 条边组成的没有重边和自环的连通无向图,一条边的长度为 Ai 。豆豆想知道他的长跑考试最少需要跑多远。

【数据范围】

对于 30% 的数据,K≤4;

对于另外 10% 的数据,K=N;

对于另外 30% 的数据,M=N-1;

对于 100% 的数据,1≤N,M≤100000;T≤5;1≤K≤n;1≤边长≤100000。

题目分析:

就是求图中最近的两个特殊点之间的距离。

  • 乱搞版:对每个特殊点进行一遍dijkstra,一遇到其他特殊点就break,更新答案。数据没有刻意去卡,加上部分分的优化勉强能卡掉。
  • 高大上的正解: 将k个点编号1...k,枚举编号的二进制的每一位,将这一位为1的点连边S(作为起点),为0的点连边T(作为终点),这样跑\(log(k)\)次dijkstra即可得到答案。总复杂度\(O(nlog(n)log(k))\),还是尽量加上部分分的优化。

code

乱搞版:

#include<bits/stdc++.h>
using namespace std; typedef long long ll; namespace IO{
inline int readint(){
int i = 0, f = 1; char ch = getchar();
for(; (ch < '0' || ch > '9') && ch != '-'; ch = getchar());
if(ch == '-') f = -1, ch = getchar();
for(; ch >= '0' && ch <= '9'; ch = getchar()) i = (i << 3) + (i << 1) + (ch - '0');
return i * f;
}
inline ll readll(){
ll i = 0, f = 1; char ch = getchar();
for(; (ch < '0' || ch > '9') && ch != '-'; ch = getchar());
if(ch == '-') f = -1, ch = getchar();
for(; ch >= '0' && ch <= '9'; ch = getchar()) i = (i << 3) + (i << 1) + (ch - '0');
return i * f;
}
inline void wrint(int x){
if(x < 0) putchar('-'), x = -x;
if(x > 9) wrint(x / 10);
putchar(x % 10 + '0');
}
inline void wrll(ll x){
if(x < 0) putchar('-'), x = -x;
if(x > 9) wrll(x / 10);
putchar(x % 10 + '0');
}
}using namespace IO; const int N = 1e5 + 5, M = 1e5 + 5, OO = 0x3f3f3f3f;
int n, m, k, ecnt, adj[N], go[M << 1], nxt[M << 1], T;
vector<int> keyPoint;
typedef pair<ll, int> P;
priority_queue<P, vector<P>, greater<P> > que;
bool key[N];
ll len[M << 1], dis[N], minn; inline void addEdge(int u, int v, ll w){ nxt[++ecnt] = adj[u], adj[u] = ecnt, go[ecnt] = v, len[ecnt] = w;} inline void solve(){
ll ret = OO;
for(int i = 0; i < k; i++){
int u = keyPoint[i];
memset(dis, OO, sizeof dis), dis[u] = 0;
while(!que.empty()) que.pop(); que.push(P(0, u));
while(!que.empty()){
P t = que.top(); que.pop();
if(t.second != u && key[t.second]){
ret = min(ret, t.first);
break;
}
for(int e = adj[t.second]; e; e = nxt[e]){
int v = go[e];
if(dis[v] > t.first + len[e]){
dis[v] = t.first + len[e];
que.push(P(dis[v], v));
}
}
}
}
wrll(ret), putchar('\n');
} int main(){
freopen("h.in", "r", stdin);
T = readint();
while(T--){
n = readint(), m = readint();
memset(adj, 0, sizeof adj), ecnt = 0, keyPoint.clear(), memset(key, 0, sizeof key), minn = OO;
for(int i = 1; i <= m; i++){
int u = readint(), v = readint();
ll w = readll(); minn = min(minn, w);
addEdge(u, v, w), addEdge(v, u, w);
}
k = readint();
for(int i = 1; i <= k; i++){ int x; keyPoint.push_back(x = readint()), key[x] = true;}
if(k == n){ wrll(minn), putchar('\n');}
else solve();
}
return 0;
}

正解:

#include<bits/stdc++.h>
using namespace std; typedef long long ll; namespace IO{
inline int readint(){
int i = 0, f = 1; char ch = getchar();
for(; (ch < '0' || ch > '9') && ch != '-'; ch = getchar());
if(ch == '-') f = -1, ch = getchar();
for(; ch >= '0' && ch <= '9'; ch = getchar()) i = (i << 3) + (i << 1) + (ch - '0');
return i * f;
}
inline ll readll(){
ll i = 0, f = 1; char ch = getchar();
for(; (ch < '0' || ch > '9') && ch != '-'; ch = getchar());
if(ch == '-') f = -1, ch = getchar();
for(; ch >= '0' && ch <= '9'; ch = getchar()) i = (i << 3) + (i << 1) + (ch - '0');
return i * f;
}
inline void wrint(int x){
if(x < 0) putchar('-'), x = -x;
if(x > 9) wrint(x / 10);
putchar(x % 10 + '0');
}
inline void wrll(ll x){
if(x < 0) putchar('-'), x = -x;
if(x > 9) wrll(x / 10);
putchar(x % 10 + '0');
}
}using namespace IO; const int N = 1e5 + 5, M = 1e5 + 5, OO = 0x3f3f3f3f;
int n, m, k, ecnt, adj[N], go[M << 1], nxt[M << 1], T;
vector<int> keyPoint;
typedef pair<ll, int> P;
priority_queue<P, vector<P>, greater<P> > que;
ll len[M << 1], dis[N], num[N], minn; inline void addEdge(int u, int v, ll w){ nxt[++ecnt] = adj[u], adj[u] = ecnt, go[ecnt] = v, len[ecnt] = w;} inline void solve(){
ll ret = OO;
for(int i = 0; (1 << i) <= k; i++){
memset(dis, OO, sizeof dis);
while(!que.empty()) que.pop();
for(int j = 0; j < keyPoint.size(); j++)
if((1 << i) & num[keyPoint[j]]) dis[keyPoint[j]] = 0, que.push(P(0, keyPoint[j]));
while(!que.empty()){
P t = que.top(); que.pop();
if(num[t.second] && !((1 << i) & num[t.second])){ ret = min(ret, t.first); break; }
for(int e = adj[t.second], v; e; e = nxt[e]){
if(dis[v = go[e]] > t.first + len[e]){
dis[v] = t.first + len[e];
que.push(P(dis[v], v));
}
}
}
}
wrll(ret), putchar('\n');
} int main(){
freopen("h.in", "r", stdin);
T = readint();
while(T--){
n = readint(), m = readint();
memset(adj, 0, sizeof adj), ecnt = 0, keyPoint.clear(), memset(num, 0, sizeof num), minn = OO;
for(int i = 1; i <= m; i++){
int u = readint(), v = readint();
ll w = readll(); minn = min(minn, w);
addEdge(u, v, w), addEdge(v, u, w);
}
k = readint();
for(int i = 1; i <= k; i++){ int x; keyPoint.push_back(x = readint()), num[x] = i;}
if(k == n) { wrll(minn), putchar('\n');}
else solve();
}
return 0;
}

NOIP模拟 path - 按二进制位分组的更多相关文章

  1. 2019.8.3 [HZOI]NOIP模拟测试12 C. 分组

    2019.8.3 [HZOI]NOIP模拟测试12 C. 分组 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 刚看这题觉得很难,于是数据点分治 k只有1和2两种,分别 ...

  2. NOIP模拟 17.8.20

    NOIP模拟17.8.20 A.阶乘[题目描述]亲爱的xyx同学正在研究数学与阶乘的关系,但是他喜欢颓废,于是他就制作了一个和阶乘有关系的数学游戏:给出两个整数 n,m,令 t = !n,每轮游戏的流 ...

  3. NOIP模拟赛20161022

    NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...

  4. contesthunter暑假NOIP模拟赛第一场题解

    contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...

  5. NOIP模拟赛 by hzwer

    2015年10月04日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...

  6. 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程

    数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...

  7. 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ...

  8. 队爷的Au Plan CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的Au%20Plan 题解:看了题之后觉得肯定是DP ...

  9. 队爷的新书 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的新书 题解:看到这题就想到了 poetize 的封 ...

随机推荐

  1. es6常用功能与异步详解(JS高级面试题)

    callback hell方法的使用 可读性不友好 function loadImg(src,callback,fail){ var img = document.createElement('img ...

  2. Flask项目之手机端租房网站的实战开发(七)

    说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...

  3. 【博客之星】CSDN2013博客之星--分析和预测

    本文纯属个人见解,多有得罪啊! 具体结果,还是看最后CSDN给的结果吧! 昵称 名字 题材 质量 数量 知名度 预测 阳光岛主 杨刚 Python,Clojure,SAE 很高 346+ 很大 一定( ...

  4. JSP中的EL表达式详细介绍

    一.JSP EL语言定义 EL 提供了在 JSP 脚本编制元素范围外使用运行时表达式的功能.脚本编制元素是指页面中能够用于在 JSP 文件中嵌入 Java 代码的元素.它们通常用于对象操作以及执行那些 ...

  5. 洛谷—— P1062 数列

    https://www.luogu.org/problem/show?pid=1062#sub 题目描述 给定一个正整数k(3≤k≤15),把所有k的方幂及所有有限个互不相等的k的方幂之和构成一个递增 ...

  6. 彻底搞懂HashMap,HashTable,ConcurrentHashMap之关联.

    注: 今天看到的一篇讲hashMap,hashTable,concurrentHashMap很透彻的一篇文章, 感谢原作者的分享.  原文地址: http://blog.csdn.net/zhange ...

  7. 【】queue

    [链接]点击打开链接 [题意] 实话实说,给 OIER 大神们排队这种工作是最让人头疼的事情了.因为同学们都有自尊 心,都不愿意排后面. 现在共有 n 个同学要排成一列,每个同学有两个属性:影响力和承 ...

  8. Java基础学习总结(50)——Java事务处理总结

    一.什么是Java事务 通常的观念认为,事务仅与数据库相关. 事务必须服从ISO/IEC所制定的ACID原则.ACID是原子性(atomicity).一致性(consistency).隔离性(isol ...

  9. jmeter与apache测试网站并发

    本文主要介绍性能测试中的常用工具jmeter的使用方式,以方便开发人员在自测过程中就能自己动手对系统进行自动压测和模拟用户操作访问请求.最后还用linux下的压测工具ab做了简单对比. 1.      ...

  10. ex.Message "ORA-01691: Lob 段 USER_MURPHY.SYS_LOB0000093717C00006$$ 无法通过 1024 (在表空间 ZJHH 中) 扩展"

    Oracle,往数据库里导入dmp的时候报错:ORA-01691:Lob 段 无法通过8192(在表空间TS_SI中)扩展 解决方案1: 原因:所创建的表空间不足. 创建一个可拓展的表空间 creat ...