【题解】Luogu P5304 [GXOI/GZOI2019]旅行者
原题传送门
题意:给你k个点,让你求两两最短路之间的最小值
我们考虑二进制拆分,使得每两个点都有机会分在不同的组\((A:0,B:1)\)中,从源点\(S\)向\(A/B\)中的点连边权为0的边,从\(B/A\)中的点向汇点\(T\)连边权为0的边,这时\(S->T\)的最短路就是\(A/B\)中的点到\(B/A\)中的点最短路的最小值
所以做最短路次数为\(2\log k\),总复杂度为\(T n \log n\log k\)(srf好像还有少一个log的做法,orz srf)
#include <bits/stdc++.h>
#define ll long long
#define N 100005
#define M 700005
#define getchar nc
using namespace std;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read()
{
register int x=0,f=1;register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x*f;
}
inline void write(register ll x)
{
if(!x)putchar('0');if(x<0)x=-x,putchar('-');
static int sta[20];register int tot=0;
while(x)sta[tot++]=x%10,x/=10;
while(tot)putchar(sta[--tot]+48);
}
inline ll Min(register ll a,register ll b)
{
return a<b?a:b;
}
struct edge{
int to,next,w;
}e[M];
int head[N],cnt,headn[N],cntn;
inline void add(register int u,register int v,register int w)
{
e[++cnt]=(edge){v,head[u],w};
head[u]=cnt;
}
inline void addn(register int u,register int v,register int w)
{
e[++cntn]=(edge){v,headn[u],w};
headn[u]=cntn;
}
int T,n,m,k,p[N],s,t;
ll dis[N];
inline ll dijkstra()
{
memset(dis,0x3f,sizeof(dis));
dis[s]=0;
priority_queue<pair<ll,int> >q;
q.push(make_pair(0,s));
for(register int i=1;i<n+2;++i)
{
while(!q.empty()&&dis[q.top().second]!=-q.top().first)
q.pop();
if(q.empty())
break;
int now=q.top().second;
q.pop();
for(register int i=headn[now];i;i=e[i].next)
{
int v=e[i].to;
if(dis[v]>dis[now]+e[i].w)
q.push(make_pair(-(dis[v]=dis[now]+e[i].w),v));
}
}
return dis[t];
}
int main()
{
int T=read();
while(T--)
{
cnt=0;
memset(head,0,sizeof(head));
n=read(),m=read(),k=read();
for(register int i=1;i<=m;++i)
{
int u=read(),v=read(),w=read();
add(u,v,w);
}
for(register int i=1;i<=k;++i)
p[i]=read();
ll ans=~0ull>>1;
s=n+1,t=n+2;
for(register int i=0;(1<<i)<=k;++i)
{
cntn=cnt;
memcpy(headn,head,sizeof(head[0])*(n+3));
for(register int j=1;j<=k;++j)
if(j&(1<<i))
addn(p[j],t,0);
else
addn(s,p[j],0);
ans=Min(ans,dijkstra());
cntn=cnt;
memcpy(headn,head,sizeof(head[0])*(n+3));
for(register int j=1;j<=k;++j)
if(j&(1<<i))
addn(s,p[j],0);
else
addn(p[j],t,0);
ans=Min(ans,dijkstra());
}
write(ans),puts("");
}
return 0;
}
【题解】Luogu P5304 [GXOI/GZOI2019]旅行者的更多相关文章
- luogu P5304 [GXOI/GZOI2019]旅行者
传送门 所以这个\(5s\)是SMG 暴力是枚举每一个点跑最短路,然后有一个很拿衣服幼稚的想法,就是把所有给出的关键点当出发点,都丢到队列里,求最短路的时候如果当前点\(x\)某个相邻的点\(y\)是 ...
- P5304 [GXOI/GZOI2019]旅行者
题目地址:P5304 [GXOI/GZOI2019]旅行者 这里是官方题解 一个图 \(n\) 点 \(m\) 条边,里面有 \(k\) 个特殊点,问这 \(k\) 个点之间两两最短路的最小值是多少? ...
- 洛谷 P5304 [GXOI/GZOI2019]旅行者(最短路)
洛谷:传送门 bzoj:传送门 参考资料: [1]:https://xht37.blog.luogu.org/p5304-gxoigzoi2019-lv-xing-zhe [2]:http://www ...
- P5304 [GXOI/GZOI2019]旅行者(最短路/乱搞)
luogu bzoj Orz自己想出神仙正解的sxy 描述略 直接把所有起点推进去跑dijkstra... 并且染色,就是记录到这个点的最短路是由哪个起点引导出来的 然后再把所有边反指跑一次... 之 ...
- [洛谷P5304][GXOI/GZOI2019]旅行者
题目大意: 有一张 \(n(n\leqslant10^5)\) 个点 \(m(m\leqslant5\times10^5)\) 条边的有向有正权图,有$k(2\leqslant k\leqslant ...
- 【BZOJ5506】[GXOI/GZOI2019]旅行者(最短路)
[BZOJ5506][GXOI/GZOI2019]旅行者(最短路) 题面 BZOJ 洛谷 题解 正着做一遍\(dij\)求出最短路径以及从谁转移过来的,反过来做一遍,如果两个点不由同一个点转移过来就更 ...
- [LOJ3087][GXOI/GZOI2019]旅行者——堆优化dijkstra
题目链接: [GXOI/GZOI2019]旅行者 我们考虑每条边的贡献,对每个点求出能到达它的最近的感兴趣的城市(设为$f[i]$,最短距离设为$a[i]$)和它能到达的离它最近的感兴趣的城市(设为$ ...
- 【题解】Luogu P5301 [GXOI/GZOI2019]宝牌一大堆
原题传送门 首先先要学会麻将,然后会发现就是一个暴力dp,分三种情况考虑: 1.非七对子国士无双,设\(dp_{i,j,k,a,b}\)表示看到了第\(i\)种牌,一共有\(j\)个\(i-1\)开头 ...
- 【题解】Luogu P5300 [GXOI/GZOI2019]与或和
原题传送门 我们珂以拆位,拆成一个个0/1矩阵 贡献珂以用全0,全1的子矩阵的个数来计算 全0,全1的子矩阵的个数珂以用悬线法/单调栈解决 #include <bits/stdc++.h> ...
随机推荐
- Sequelize 数据类型
Sequelize.STRING // VARCHAR(255)Sequelize.STRING(1234) // VARCHAR(1234)Sequelize.STRING.BINARY // VA ...
- Xor-matic Number of the Graph-CodeForces - 724G
Xor-matic Number of the Graph-CodeForces - 724G 线性基棒题 建议做这题前先看看线性基的概念,然后A掉这道题--->路径最大异或和 这两个题都用到了 ...
- vector内存释放问题
一般,如果vector中存放是的指针,那么必须先遍历一遍,释放指针所指向的内存.(如果vector的元素是内置类型,那么就没有必要做这一步) 然后在释放vector中各元素所占内存,这时候可以用swa ...
- [Beta阶段]第六次Scrum Meeting
Scrum Meeting博客目录 [Beta阶段]第六次Scrum Meeting 基本信息 名称 时间 地点 时长 第六次Scrum Meeting 19/05/12 大运村寝室6楼 25min ...
- EAccessViolation
Access Violation(非法访问),General Protection Fault(一般保护性错误)或者Invalid Page Fault(无效页面错误),虽然说法不一样,但本质上总是由 ...
- 如何完美更换WordPress网站的域名
前几天,一位WordPress王牌主机的用户问我,他的WordPress网站已经建立一年多了,现在想要修改网站使用的域名,该如何操作?这是WordPress用户经常遇到的问题.今天我们来给大家介绍一下 ...
- stream_context_create解析
(PHP 4 >= 4.3.0, PHP 5, PHP 7) stream_context_create — 创建资源流上下文 说明¶ stream_context_create ([ arra ...
- MyBatis(八):Mybatis Java API枚举类型转化的用法
最近工作中用到了mybatis的Java API方式进行开发,顺便也整理下该功能的用法,接下来会针对基本部分进行学习: 1)Java API处理一对多.多对一的用法: 2)增.删.改.查的用法: 3) ...
- Windows curl开启注意事项
php.ini 开启curl扩展 设置有时候开启之后,curl还是不行:将php目录下的libssh2.dll复制到apache/bin下.(基本上可以成功) 如果没有开启成功,将php安装目录下 ...
- 【jmeter】使用csv文件生成用户名和密码列表
介绍 在[jmeter]使用jmeter进行测试-示例 中介绍了jmeter的基本使用,本文将介绍如何使用csv文件生成多个用户名. 应用场景 实际测试中,经常需要模拟多个用户进行负载测试,而用户名和 ...