题目描述

最近,Elaxia和w**的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间。

Elaxia和w**每天都要奔波于宿舍和实验室之间,他们 希望在节约时间的前提下,一起走的时间尽可能的长。

现在已知的是Elaxia和w**所在的宿舍和实验室的编号以及学校的地图:地图上有N个路 口,M条路,经过每条路都需要一定的时间。 具体地说,就是要求无向图中,两对点间最短路的最长公共路径。

解析

这个题,怎么说呢,对我来说思维难度还是比较低的,但是代码难度稍微就高了点。

题目清楚的告诉我们要求两对点之间最短路的最大公共路径。实际上两点之间的最短路可能有多条,于是我们就要把它们都标出来。题目还提到希望在节约时间的前提下,一起走的时间尽可能的长,因此我们并不一定需要两人都只走各自的最短路,我们只需要让最终答案最优即可(即不能再更节约时间,一起走的时间不能再更长)。为了更好表示,我们引入一些符号。

设\(x1,y1\)之间所有最短路的边的集合为\(A\),\(x2,y2\)之间所有最短路的边的集合为\(B\)。我们首先要做的是找出这两个集合,然后比对\(A\)和\(B\),找出一个集合\(C\in A \cap B\),它就是两点对所有最短路径的公共边。

此时,我们只需要在\(C\)中找出一条最长的简单路径即可。为什么是简单路径呢,因为最短路本身就是简单路径嘛(废话)。

首先标记最短路上的边很容易,我们分别从起点终点两端点跑两遍最短路算法,然后再对每条边进行检查。假设起点为\(s\),终点为\(t\),对于某个点\(x\),它扩展出的点为\(y\),它们之间的边\(c(x,y)=z\),\(d[x]\)为到\(x\)点的最短路,如果有\(d[x]+d'[y]+z=d[t]\),那么这条边在\(s\rightarrow t\)最短路上。所以两对点我们要跑四次。注意,如果我们不跑两遍最短路的话,该方法会标记所有可达边。

所以接下来怎么找\(C\)中的最长简单路径呢?说实话我没想出来。

一开始打算在第二轮最短路时搞一个类似递推的东西统计。显然对于某个点\(y\),它可以由很多个点扩展而来,而我们只选取其中使得最长公共路径最大的一个点\(x\)扩展过来(当然首先这条边\(c(x,y)\)得在\(C\)中)。然而本人能力实在有限,并没有没码出来(就是菜)。看到题解里似乎也有人这么写,并且过了,我枯了。

遂看了题解,震惊,竟然可以用拓扑排序?!(我才不写什么狗屁重载呢,麻烦的很)

我还在纳闷无向图怎么搞拓扑的时候,人家已经想到分析两人同方向走和反方向走两种情况了!意思就是说我们可以考虑两人同方向和反方向走两种情况的最长公共路径,妙哉!

因此我们需要对两张图进行拓扑排序找最长链:\(x1\rightarrow y1\)所有最短路上的边按照\(x1\rightarrow y1\)的方向存,\(x2\rightarrow y2\)的所有最短路上的边按照\(x2\rightarrow y2\)的方向存的图1;\(x1\rightarrow y1\)所有最短路上的边按照\(x1\rightarrow y1\)的方向存,\(y2\rightarrow x2\)的所有最短路上的边按照\(y2\rightarrow x2\)的方向存的图2,注意这些最短路边包含在\(C\)中。

最后在两张图的最优解中择优。

神奇。

参考代码

#include<cstdio>
#include<iostream>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#define N 3010
using namespace std;
inline int read()
{
int f=1,x=0;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
struct rec{
int next,ver,edge;
}g[N*N],G[N*N];
int head[N],tot,headG[N],totG,n,m,x1,x2,y1,y2;
int d[4][N],ing[N],c[N];
bool v[N];
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q;
inline void add(int x,int y,int val)
{
g[++tot].ver=y,g[tot].edge=val;
g[tot].next=head[x],head[x]=tot;
}
inline void addG(int x,int y,int val)
{
G[++totG].ver=y,G[totG].edge=val;
G[totG].next=headG[x],headG[x]=totG;
ing[y]++;
}
inline void dijkstra(int k,int x)
{
memset(d[k],0x3f,sizeof(d[k]));
memset(v,0,sizeof(v));
d[k][x]=0;q.push(make_pair(0,x));
while(q.size()){
int index=q.top().second;q.pop();
if(v[index]) continue;
v[index]=1;
for(int i=head[index];i;i=g[i].next){
int y=g[i].ver,z=g[i].edge;
if(d[k][y]>d[k][index]+z){
d[k][y]=d[k][index]+z;
q.push(make_pair(d[k][y],y));
}
}
}
}
inline void sign(int k)
{
for(int i=1;i<=n;++i)
for(int j=head[i];j;j=g[j].next){
int y=g[j].ver,z=g[j].edge;
if(d[0][i]+z+d[2][y]==d[0][y1]&&d[1][i]+z+d[3][y]==d[1][y2]&&k==1)
addG(i,y,z);
if(d[0][i]+z+d[2][y]==d[0][y1]&&d[3][i]+z+d[1][y]==d[1][y2]&&k==2)
addG(i,y,z);
}
}
int main()
{
n=read(),m=read();
x1=read(),y1=read(),x2=read(),y2=read();
for(int i=1;i<=m;++i){
int u,v,val;
u=read(),v=read(),val=read();
add(u,v,val),add(v,u,val);
}
dijkstra(0,x1),dijkstra(1,x2);
dijkstra(2,y1),dijkstra(3,y2);
//topsort
int ans=0;
queue<int> Q;
sign(1);
for(int i=1;i<=n;++i)
if(ing[i]==0) Q.push(i);
while(Q.size()){
int x=Q.front();Q.pop();
for(int i=headG[x];i;i=G[i].next){
int y=G[i].ver,z=G[i].edge;
if(--ing[y]==0){
c[y]=max(c[x]+z,c[y]);
ans=max(ans,c[y]);
Q.push(y);
}
}
}
memset(ing,0,sizeof(ing));
memset(headG,0,sizeof(headG));
memset(c,0,sizeof(c));
sign(2);
for(int i=1;i<=n;++i)
if(ing[i]==0) Q.push(i);
while(Q.size()){
int x=Q.front();Q.pop();
for(int i=headG[x];i;i=G[i].next){
int y=G[i].ver,z=G[i].edge;
if(--ing[y]==0){
c[y]=max(c[x]+z,c[y]);
ans=max(ans,c[y]);
Q.push(y);
}
}
}
cout<<ans<<endl;
return 0;
}

P2149 [SDOI2009]Elaxia的路线[最长公共路径]的更多相关文章

  1. 洛谷 P2149 [SDOI2009]Elaxia的路线 解题报告

    P2149 [SDOI2009]Elaxia的路线 题目描述 最近,Elaxia和w**的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间. Elaxia ...

  2. 洛谷——P2149 [SDOI2009]Elaxia的路线

    P2149 [SDOI2009]Elaxia的路线 题目描述 最近,Elaxia和w的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间.Elaxia和w每 ...

  3. Luogu P2149 [SDOI2009]Elaxia的路线(最短路+记忆化搜索)

    P2149 [SDOI2009]Elaxia的路线 题意 题目描述 最近,\(Elaxia\)和\(w**\)的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们必须合理地安排两个人在一起的 ...

  4. P2149 [SDOI2009]Elaxia的路线

    题目描述 最近,Elaxia和w**的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间. Elaxia和w**每天都要奔波于宿舍和实验室之间,他们 希望在 ...

  5. 洛谷 P2149 [SDOI2009]Elaxia的路线

    题目描述 最近,Elaxia和w的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间.Elaxia和w每天都要奔波于宿舍和实验室之间,他们 希望在节约时间的 ...

  6. 洛谷—— P2149 [SDOI2009]Elaxia的路线

    https://www.luogu.org/problem/show?pid=2149 题目描述 最近,Elaxia和w的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两 ...

  7. Luogu P2149 [SDOI2009]Elaxia的路线 | 图论

    题目链接 题解: 题面中给了最简洁清晰的题目描述:"求无向图中,两对点间最短路的最长公共路径". 对于这个问题我们可以先考虑图中的哪些边对这两对点的最短路产生了贡献. 比如说下面这 ...

  8. bzoj1880: [Sdoi2009]Elaxia的路线(spfa,拓扑排序最长路)

    1880: [Sdoi2009]Elaxia的路线 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 1944  Solved: 759[Submit][St ...

  9. Spfa+DP【p2149】[SDOI2009]Elaxia的路线

    Description 最近,Elaxia和w**的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间. Elaxia和w**每天都要奔波于宿舍和实验室之间 ...

随机推荐

  1. jquery鼠标经过弹出层写法

    jquery鼠标经过弹出层写法<pre><div class="navitem"><a href="/index.php?c=news&am ...

  2. python 之 Django框架(路由系统、include、命名URL和URL反向解析、命名空间模式)

    12.36 Django的路由系统 基本格式: from django.conf.urls import url urlpatterns = [ url(正则表达式, views视图函数,参数,别名) ...

  3. python 之 前端开发( jQuery选择器、筛选器、样式操作、文本操作、属性操作、文档操作)

    11.5 jQuery 引入方式: 方式一:本地引入 <script src="jquery-3.3.1.min.js"></script> <scr ...

  4. python学习-69 包装和授权

    包装 1.二次加工标准类型(包装) class List(list): def append(self, a_objcet): if type(a_objcet) is str: super().ap ...

  5. python实现查找最长公共子序列

    #!/usr/bin/python # -*- coding: UTF-8 -*- worlds = ['fosh','fort','vista','fish','hish','hello','ohd ...

  6. PAT(B) 1090 危险品装箱(Java)

    题目链接:1090 危险品装箱 (25 point(s)) 题目描述 集装箱运输货物时,我们必须特别小心,不能把不相容的货物装在一只箱子里.比如氧化剂绝对不能跟易燃液体同箱,否则很容易造成爆炸. 本题 ...

  7. go 渲染数据到文件

    //把数据写到文件里面 package main import ( "fmt" "text/template" "time" "o ...

  8. 我的Vue朝圣之路1

    1. Vue是什么? 1). 一位华裔前Google工程师开发的前端js库         2). 一个MVVM框架         3). 核心概念              * 数据绑定      ...

  9. 深度自适应增量学习(Incremental Learning Through Deep Adaptation)

    深度自适应增量学习(Incremental Learning Through Deep Adaptation) 2018-05-25 18:56:00 木呆呆瓶子 阅读数 10564  收藏 更多 分 ...

  10. 长连接、短连接、长轮询和WebSocket

    //转发,格式待整理 2017-08-0519784View0 对这四个概念不太清楚,今天专门搜索了解一下,总结一下: 长连接:在HTTP 1.1,客户端发出请求,服务端接收请求,双方建立连接,在服务 ...