题目链接

多次询问求仙人掌上两点间的最短路径。

如果是在树上,那么求LCA就可以了。

先做着,看看能不能把它弄成树。

把仙人掌看作一个图(实际上就是),求一遍根节点到每个点的最短路dis[i]。

对于u,v,若w=LCA(u,v)不在环上(u,v不同在一个环),那么dis(u,v)可以像在树上一样直接求得。

若w=u||w=v,(且w不是环内的一个点),dis(u,v)=dis[u/v]-dis[w]。

如果w在环上,那么设x,y为u,v往上距离最近的环上的离u,v最近的两个点,那么dis(u,v)=dis[u]-dis[x]+dis[v]-dis[y]+(x,y在环上的最短距离)。

设cdis[i]为按DFS序得到的根节点到i的距离,len[i]为环i的长,x,y在环上的最短距离就是min(abs(cdis[x]-cdis[y]),len[bel]-abs(cdis[x]-cdis[y]))。

怎么把它弄成一棵树 求LCA?

所有在一个环上的点以这个环深度最小的点作为父节点,由父节点向子节点连边就行了。之前缩一下点。

求仙人掌上单源最短路可以O(n)DP

太弱不会。。

这代码总感觉有问题,果然。。这就卡掉了

8 9 1

1 2 10

2 3 10

4 7 5

4 6 10

4 5 10

4 3 10

5 1 10

6 7 16

7 8 10

7 8

重写吧。。在这儿,正好练练圆方树

//6492kb	376ms
#include <queue>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define gc() getchar()
#define mp std::make_pair
#define pr std::pair<int,int>
const int N=1e4+5,M=2e5+5; int n,m,Q,Enum,H[N],nxt[M<<1],to[M<<1],val[M<<1],dis[N],cnt,bel[N],len[N],cdis[N],dep[N],fa[N][16];
std::priority_queue<pr> q;
bool vis[N],vis2[N]; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline void AddEdge(int u,int v,int w){
to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum, val[Enum]=w;
to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum, val[Enum]=w;
}
void Dijkstra()
{
memset(dis,0x3f,sizeof dis);
dis[1]=0, q.push(mp(0,1));
while(!q.empty())
{
int x=q.top().second; q.pop();
if(vis2[x]) continue;
vis2[x]=1;
for(int i=H[x]; i; i=nxt[i])
if(dis[to[i]]>dis[x]+val[i])
dis[to[i]]=dis[x]+val[i], q.push(mp(-dis[to[i]],to[i]));
}
}
void DFS(int x)
{
vis[x]=1;
for(int v,i=H[x]; i; i=nxt[i])
if(to[i]!=fa[x][0]&&!bel[to[i]])
if(!vis[v=to[i]]) fa[v][0]=x,cdis[v]=cdis[x]+val[i],dep[v]=dep[x]+1,DFS(v);
else{//find a circle v
len[++cnt]=cdis[x]-cdis[v]+val[i];
for(int j=x,pre; j!=v; j=pre)
bel[j]=cnt, pre=fa[j][0], fa[j][0]=v;
//不给bel[v]赋值,因为v可能作为多个环的交点。
}
}
void Init_LCA()
{
for(int x=2; x<=n; ++x)
// for(int i=1; i<16&&dep[x]>=(1<<i); ++i)
for(int i=1; i<16; ++i)
fa[x][i]=fa[fa[x][i-1]][i-1];
}
void Query_LCA(int &u,int &v)
{
if(dep[u]<dep[v]) std::swap(u,v);
for(int i=15; ~i; --i)
if(dep[fa[u][i]]>=dep[v]) u=fa[u][i];//这样dep[1]=1!
if(u==v) return;
for(int i=15; ~i; --i)
if(fa[u][i]!=fa[v][i]) u=fa[u][i],v=fa[v][i];
// u=fa[u][0], v=fa[v][0];
}
void DFS_for_Deep(int x){
for(int i=H[x]; i; i=nxt[i])
if(to[i]!=fa[x][0]) dep[to[i]]=dep[x]+1, DFS_for_Deep(to[i]);
} int main()
{
n=read(),m=read(),Q=read();
for(int u,v,i=1; i<=m; ++i) u=read(),v=read(),AddEdge(u,v,read());
Dijkstra(), DFS(1);
Enum=0, memset(H,0,sizeof H);
for(int i=2; i<=n; ++i) AddEdge(fa[i][0],i,0);
dep[1]=1, DFS_for_Deep(1)/*在新树上得到dep啊。。*/, Init_LCA();
int u,v,x,y,l;
while(Q--)
{
u=read(),v=read(),Query_LCA(x=u,y=v);//此时的x,y若在环上,则是最接近u,v的环上的点(再往上跳一步就是LCA,环深度最低的点)
if(x!=y && bel[x] && bel[x]==bel[y])//x!=y即u,v不是在一条链上 //注意判bel[x]!=0!
printf("%d\n",dis[u]+dis[v]-dis[x]-dis[y]+std::min(std::abs(cdis[x]-cdis[y]),len[bel[x]]-std::abs(cdis[x]-cdis[y])));
else if(x==y) printf("%d\n",dis[u]+dis[v]-(dis[x]<<1));
else printf("%d\n",dis[u]+dis[v]-(dis[fa[x][0]]<<1));//不在一个环上也直接更新。
}
return 0;
}

BZOJ.2125.最短路(仙人掌 最短路Dijkstra)的更多相关文章

  1. 最短路和次短路问题,dijkstra算法

    /*  *题目大意:  *在一个有向图中,求从s到t两个点之间的最短路和比最短路长1的次短路的条数之和;  *  *算法思想:  *用A*求第K短路,目测会超时,直接在dijkstra算法上求次短路; ...

  2. hdu1688(dijkstra求最短路和次短路)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1688 题意:第k短路,这里要求的是第1短路(即最短路),第2短路(即次短路),以及路径条数,最后如果最 ...

  3. bzoj 1726: [Usaco2006 Nov]Roadblocks第二短路【dijskstra】

    严格次短路模板,用两个数组分别维护最短路和次短路,用dijskstra,每次更新的时候先更新最短路再更新次短路 写了spfa版的不知道为啥不对-- #include<iostream> # ...

  4. poj 3463 Sightseeing( 最短路与次短路)

    http://poj.org/problem?id=3463 Sightseeing Time Limit: 2000MS   Memory Limit: 65536K Total Submissio ...

  5. POJ---3463 Sightseeing 记录最短路和次短路的条数

    Sightseeing Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 9247   Accepted: 3242 Descr ...

  6. POJ 3463 Sightseeing 【最短路与次短路】

    题目 Tour operator Your Personal Holiday organises guided bus trips across the Benelux. Every day the ...

  7. UESTC30-最短路-Floyd最短路、spfa+链式前向星建图

    最短路 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) 在每年的校赛里,所有进入决赛的同 ...

  8. CF 672C 两个人捡瓶子 最短路与次短路思想

    C. Recycling Bottles time limit per test 2 seconds memory limit per test 256 megabytes input standar ...

  9. POJ - 3463 Sightseeing 最短路计数+次短路计数

    F - Sightseeing 传送门: POJ - 3463 分析 一句话题意:给你一个有向图,可能有重边,让你求从s到t最短路的条数,如果次短路的长度比最短路的长度多1,那么在加上次短路的条数. ...

随机推荐

  1. Hadoop基础-MapReduce的Combiner用法案例

    Hadoop基础-MapReduce的Combiner用法案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.编写年度最高气温统计 如上图说所示:有一个temp的文件,里面存放 ...

  2. Swift学习笔记2

    1.函数参数都有一个外部参数名(external parameter name)和一个局部参数名(local parameter name).外部参数名用于在函数调用时标注传递给函数的参数,局部参数名 ...

  3. bzoj千题计划186:bzoj1048: [HAOI2007]分割矩阵

    http://www.lydsy.com/JudgeOnline/problem.php?id=1048 #include<cmath> #include<cstdio> #i ...

  4. Parquet 格式文件

    Apache Parquet是Hadoop生态圈中一种新型列式存储格式,它可以兼容Hadoop生态圈中大多数计算框架(Hadoop.Spark等),被多种查询引擎支持(Hive.Impala.Dril ...

  5. tweenMax学习笔记

    tweenMax是一款缓动插件,能实现很多牛逼的效果,在网上看了些demo,确实很吊,虽说很多用CSS3也能做出来,但是技多不压身,学之. 网上的demo还是很多的,但是资料不多,唯一能够让我有思绪的 ...

  6. [C]语法, 知识点总结(二. 结构体, 类别名, static, const)

    结构体 定义: struct Student{ // 定义结构体Student, stu是创建的对象         char a[17]; // 结构体里面可以有多种不同类型的变量         ...

  7. ASP.NET MVC3-Music Store中英文教程 [下载]

    翻译原文档名: MVC Music Store版本: ASP.NET MVC3概述Mvc Music Store 是一个为WEB开发人员一步一步介绍和解释如何使用MVC和Visual Web开发的应用 ...

  8. 仿QQ聊天图文混排流程图【适用于XMPP】

      图文混排流程图.graffle4.8 KB   下面附上图片素材: 表情.zip692.5 KB     下面是字符串与图片的详细对应关系:                 "[呲牙]& ...

  9. redis从入门到踩坑

    背景 Redis在互联网项目的使用也是非常普遍的,作为最常用的NO-SQL数据库,对Redis的了解已经成为了后端开发的必备技能.小编对Redis的使用时间不长,但是项目中确两次踩中了Redis的坑, ...

  10. Git 使用规范流程【转】

    转自:http://www.ruanyifeng.com/blog/2015/08/git-use-process.html 作者: 阮一峰 日期: 2015年8月 5日 团队开发中,遵循一个合理.清 ...