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 ...
随机推荐
- uboot中MAC网络(待续)
start ->start_armboot ->main_loop 实际应用中问题:为什么从nandflash读出的MAC(写到物理phy上)与上层网口地址不同(上层网口采用env的mac ...
- form_tag
class SwitchesController < ApplicationController #before_filter :authenticate_user!, :except => ...
- Windoows窗口程序一
编写窗口程序的步骤: .定义WinMain入口函数 .定义窗口处理函数(处理消息)WindowProc .注册窗口类RegisterClass .创建窗口(在内存中创建窗口)CreateWindow ...
- OpenMediaVault的OwnCloud扩展不支持NTFS格式硬盘
来源https://forum.openmediavault.org/index.php/Thread/15510-OwnCloud-Operation-not-supported-setfacl/ ...
- 从my里调出数据插入到ms2008 骨架 php
<?php $server ="XEJMZWMDIXE9CIJ";//ms,服务器IP地址,如果是本地,可以写成localhost $uid =""; / ...
- 关于SQL语句的一些注意事项
1.Into 表后要编辑-IntelliSense-刷新本地缓存 才能访问新表 2.Is null不是=null
- kafka学习之-配置详解
# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreement ...
- jQuery语法小结(超实用)
1.关于页面元素的引用 通过jquery的$()引用元素包括通过id.class.元素名以及元素的层级关系及dom或者xpath条件等方法,且返回的对象为jquery对象(集合对象),不能直接调用do ...
- 谈谈django里的Contex和RequestContext---向模板里添加全局变量
一直很想仔细研究一下,我在django模板里,可以直接访问变量user, request之类的变量,哪里来的,到底都有哪些?这会儿周五,我有空来仔细看看代码. 模拟一下需求: 我们做一个在线商城,需要 ...
- Android问题集锦之三十四:android studio导入项目下载gradle-x.x.x-all.zip
每每打开github上的项目,都会先下载gradle.每一个项目都有自己的gradle构建程序,可是打开一个新项目就又一次下载gradle对于网络较差的情况真是苦不堪言.所以我们能够用已经下载好的放到 ...