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 ...
随机推荐
- git中文乱码解决方案
解决方案: 在bash提示符下输入: git config --global core.quotepath false core.quotepath设为false的话,就不会对0x80以上的字符进行q ...
- FluentData - 轻量级.NET ORM持久化技术解决方式
FluentData - 轻量级.NET ORM持久化技术解决方式 文件夹: 一.什么是ORM? 二.使用ORM的优势 三.使用ORM的缺点 四.NET下的ORM框架有哪些? 五.几 ...
- iOS边练边学--图片的拉伸
图片拉伸方法一: IOS 5.0以后才有的方法: - (void)viewDidLoad { [super viewDidLoad]; UIImageView *imageView = [[UIIma ...
- DataGridView使用技巧七:列顺序的调整、操作行头列头的标题
一.列顺序的调整 设定DataGridView的AllowUserToOrderColumns为True的时候,用户可以自由调整列的顺序. 当用户改变列的顺序的时候,其本身的Index不好改变,但是D ...
- nginx反向代理压测问题记录
使用nginx反向代理压测web程序,100个用户并发时,每隔一段时间loadrunner工具中就会报错,报错信息如下: Continuing after Error -26610: HTTP Sta ...
- rar安装和使用
参考:http://blog.csdn.net/dracotianlong/article/details/18011033 .下载rar wget http://www.rarlab.com/rar ...
- e581. Animating an Array of Images in an Application
This is the simplest application to animate an array of images. import java.awt.*; import javax.swin ...
- Powershell 的自己主动部署
工作中反复性的版本号移植,一天上线10几次,让我痛不欲生,频繁的操作也可能出现疲劳性失误,导致严重的生产故障.于是乎,闲暇时间.我開始研究使用powershell自己主动部署程序到Linuxse ...
- ThinkPHP Mongo驱动update方法支持upsert参数
Mongo数据库update操作有一个相对于Mysql的关键特性,它可以使用upsert模式,当更新的数据不存在时,直接插入,但是ThinkPHP的Mongo驱动居然不支持这一特性,没办法,自力更生了 ...
- 属性编辑器,即PropertyEditor-->Spring IoC
在Spring配置文件里,我们往往通过字面值为Bean各种类型的属性提供设置值:不管是double类型还是int类型,在配置文件中都对应字符串类型的字面值.BeanWrapper填充Bean属性时如何 ...