JZOJ.5287【NOIP2017模拟8.16】最短路
Description
Input
Output
Sample Input
9 10 2
1 2 1
1 4 1
3 4 1
2 3 1
3 7 1
7 8 2
7 9 2
1 5 3
1 6 4
5 6 1
1 9
5 7
Sample Output
5
6
Data Constraint
容易发现这是一张仙人掌图(每条边最多属于一个环的无向连通图)
仙人掌图求最短路的常用处理方法是将它变成一棵树,原图里为环的点更改为该环上的点都指向该环的某个点A,然后边长就是该点到点A的最短路径。
再预处理每个点到顶点的距离dis。
然后对于询问的两个点u,v,如果u,v的LCA不在环上,那么距离就直接是dis[u]+dis[v]-2*dis[LCA(u,v)].
如果在环上,那么对于它们进入环的点Cu,Cv则有两种走法,一种是从Cu顺时针走向Cv,另一种是从Cu逆时针走向Cv,两者取最小再加上dis[u]+dis[v]-dis[Cu]-dis[Cv]就可以了。
至于求环,我们可以运用Tarjan的思想。求LCA用倍增就可以了。值得注意的是,这里可以一个点在两个环里。
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cmath>
#define N 400005
using namespace std;
struct data{
int next,to,power;
}l1[N],l2[N];
int n,m,q,f1[N/],f2[N/],dfn[N/],num1,num2,head1[N],head2[N],zhan[N],top,up[N][],t,deep[N],dis[N/],belong[N],f[N/],visit[N/],host[N/],cnt;
int read(){
int x=,w=;
char c=;
for (c=getchar();c<''||c>'';c=getchar()) {if (c=='-') w=-;}
for (;c>=''&&c<='';c=getchar()) x=(x<<)+(x<<)+c-'';
return x*w;
}
void write(long long x){
if (!x) putchar('');else{
char s[];
int i,j=;
for (;x>;x/=) s[j++]=x%;
for (i=j-;i>=;i--) putchar(s[i]+);
}
putchar('\n');
}
void add1(int u,int v,int w){
num1++;
l1[num1].next=head1[u];
l1[num1].to=v;
l1[num1].power=w;
head1[u]=num1;
num1++;
l1[num1].next=head1[v];
l1[num1].to=u;
l1[num1].power=w;
head1[v]=num1;
}
void add2(int u,int v,int w){
num2++;
l2[num2].next=head2[u];
l2[num2].to=v;
l2[num2].power=w;
head2[u]=num2;
num2++;
l2[num2].next=head2[v];
l2[num2].to=u;
l2[num2].power=w;
head2[v]=num2;
}
void DFS(int x){
dfn[x]=++t;
for (int v=,i=head1[x];i;i=l1[i].next){
v=l1[i].to;
if ((v!=f[x])&&(!dfn[v])){
f[v]=x;
zhan[++top]=i;
DFS(v);
}
else if ((v!=f[x])&&(dfn[v]<dfn[x])){
long long sum=l1[i].power;
int p=top;
while ((l1[zhan[p]].to!=v)&&(p)){
f1[l1[zhan[p]].to]=sum;
sum+=l1[zhan[p]].power;
p--;
}
cnt++;
sum=l1[zhan[p+]].power;
for (int j=p+;j<=top;++j){
f2[l1[zhan[j]].to]=sum;
host[l1[zhan[j]].to]=v;
belong[l1[zhan[j]].to]=cnt;
add2(v,l1[zhan[j]].to,min(f1[l1[zhan[j]].to],f2[l1[zhan[j]].to]));
sum+=l1[zhan[j+]].power;
}
}
}
top--;
}
void build(int x){
visit[x]=;
for (int v=,i=head1[x];i;i=l1[i].next){
v=l1[i].to;
if ((!visit[v])&&(v!=f[x])){
if (((belong[x]!=belong[v])||((!belong[x])&&(!belong[v])))&&(host[x]!=v)&&(host[v]!=x))
add2(x,v,l1[i].power);
build(v);
}
}
}
void pre(int x){
deep[x]=deep[f[x]]+;
up[x][]=f[x];
for (int i=;i<=;++i)
up[x][i]=up[up[x][i-]][i-];
for (int v=,i=head2[x];i;i=l2[i].next){
v=l2[i].to;
if ((!deep[v])&&(v!=f[x])) {
f[v]=x;
dis[v]=dis[x]+l2[i].power;
pre(v);
}
}
}
int lca(int u,int v,int www){
int a=u,b=v;
if (deep[u]<deep[v]) swap(u,v);
for (int i=;i>=;--i)
if (deep[v]<=deep[up[u][i]])
u=up[u][i];
if (u==v) return (dis[a]-dis[u]+dis[b]-dis[v]);
for (int i=;i>=;--i)
if (up[v][i]!=up[u][i]){
v=up[v][i];
u =up[u][i];
}
if ((u!=v)&&(belong[u])&&(belong[u]==belong[v])) return (dis[a]-dis[u]+dis[b]-dis[v]+min(min(f1[u]+f2[v],f1[v]+f2[u]),min(abs(f1[u]-f1[v]),abs(f2[u]-f2[v]))));
else return (dis[a]-dis[up[u][]]+dis[b]-dis[up[v][]]);
}
int main(){
n=read(),m=read(),q=read();
t=,num1=,num2=,top=,cnt=;
for (int v=,u=,w=,i=;i<=m;++i){
u=read(),v=read(),w=read();
add1(u,v,w);
}
deep[]=-;
f[]=;
dis[]=;
DFS();
build();
f[]=;
pre();
for (int u=,v=,i=;i<=q;++i){
u=read(),v=read();
write(lca(u,v,i));
}
return ;
}
神奇的代码
拖欠了好几天的题终于A了QAQ
JZOJ.5287【NOIP2017模拟8.16】最短路的更多相关文章
- JZOJ.5286【NOIP2017模拟8.16】花花的森林
Description
- JZOJ.5285【NOIP2017模拟8.16】排序
Description
- [jzoj 5343] [NOIP2017模拟9.3A组] 健美猫 解题报告 (差分)
题目链接: http://172.16.0.132/senior/#main/show/5343 题目: 题解: 记旋转i次之后的答案为$ans_i$,分别考虑每个元素对ans数组的贡献 若$s_i& ...
- [JZOJ 5908] [NOIP2018模拟10.16] 开荒(kaihuang)解题报告 (树状数组+思维)
题目链接: https://jzoj.net/senior/#contest/show/2529/1 题目: 题目背景:尊者神高达作为一个萌新,在升级路上死亡无数次后被一只大黄叽带回了师门.他加入师门 ...
- [JZOJ 5909] [NOIP2018模拟10.16] 跑商(paoshang) 解题报告 (圆方树)
题目链接: https://jzoj.net/senior/#contest/show/2529/2 题目: 题目背景:尊者神高达很穷,所以他需要跑商来赚钱题目描述:基三的地图可以看做 n 个城市,m ...
- JZOJ 5286. 【NOIP2017提高A组模拟8.16】花花的森林 (Standard IO)
5286. [NOIP2017提高A组模拟8.16]花花的森林 (Standard IO) Time Limits: 1000 ms Memory Limits: 131072 KB Descript ...
- JZOJ 5236. 【NOIP2017模拟8.7A组】利普希茨
5236. [NOIP2017模拟8.7A组]利普希茨 (File IO): input:lipschitz.in output:lipschitz.out Time Limits: 1000 ms ...
- JZOJ 【NOIP2017提高A组模拟9.14】捕老鼠
JZOJ [NOIP2017提高A组模拟9.14]捕老鼠 题目 Description 为了加快社会主义现代化,建设新农村,农夫约(Farmer Jo)决定给农庄里的仓库灭灭鼠.于是,猫被农夫约派去捕 ...
- JZOJ 5246. 【NOIP2017模拟8.8A组】Trip(trip)
5246. [NOIP2017模拟8.8A组]Trip(trip) (File IO): input:trip.in output:trip.out Time Limits: 1500 ms Memo ...
随机推荐
- 缓存之 ACache
1.android缓存的介绍 Android开发本质上就是手机和互联网中的webserver之间进行通信,就必定须要从服务端获取数据.而重复通过网络获取数据是比較耗时的.特别是訪问比較多的时候.会极大 ...
- Akka 编程: 什么是Actor
上一篇我们简介了Actor系统.说明了Actor之间存在着层次关系,它也是构成Actor应用的最主要的单位. 本篇介绍Actor本身的一些基本概念.一个Actor包括了State(状态),Behavi ...
- datanode启动失败
当我动态加入一个hadoop从节点的之后,出现了一个问题: [root@hadoop current]# hadoop-daemon.sh start datanode starting datano ...
- es 配置文件
[root@es02 config]# egrep -v "^(#|$)" elasticsearch.yml cluster.name: v5-applicationnode.n ...
- VMware ESXi 不支持NTFS格式的USB外接硬盘
本来想搞直通USB外接大容量硬盘(希捷Seagate Backup+ Hub WH 8T),实现在同一部ESXi下,直接将NAS的数据转移到外接硬盘.结果发现虚拟机下的win server系统识别不了 ...
- Openfire配置过程,以及与php交互注意事项。
Ben Werdmuller 是一位 Web 策划师和开发人员,他专注于开放源码平台.他是开源社交网络框架 Elgg 的共同创始人和技术带头人.Ben 的博客 http://benwerd.com/. ...
- 【转】Microsoft .Net Remoting之Marshal、Disconnect与生命周期以及跟踪服务
Marshal.Disconnect与生命周期以及跟踪服务 一.远程对象的激活 在Remoting中有三种激活方式,一般的实现是通过RemotingServices类的静态方法来完成.工作过程事实上是 ...
- 将ORACLE数据库更改为归档模式;写出步骤
解答:具体步骤如下: 1),以exp方式在线备份数据库到指定位置: 2),观察当前数据库是以服务器参数文件(spfile)方式启动还是以参数文件(pfile)方式启动: SQL> show pa ...
- C#代理多样性
一.代理 首先我们要弄清代理是个什么东西.别让一串翻译过来的概念把大家搞晕了头.有的文章把代理称委托.代表等,其实它们是一个东西,英文表述都是“Delegate”.由于没有一本权威的书来规范这个概念, ...
- linux -- Ubuntuserver图形界面下安装、配置lampp、phpmyadmin
PHP开发和服务器运行环境首选LAMP组合,即Linux+Apache+Mysql+Php/Perl/Python,能最优化服务器性能.如何在本地电脑Ubuntu 中安装和配置LAMP环境搭建?Ubu ...