Description

最近,Elaxia和w的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间。Elaxia和w每天都要奔波于宿舍和实验室之间,他们 希望在节约时间的前提下,一起走的时间尽可能的长。 现在已知的是Elaxia和w所在的宿舍和实验室的编号以及学校的地图:地图上有N个路 口,M条路,经过每条路都需要一定的时间。 具体地说,就是要求无向图中,两对点间最短路的最长公共路径。

solution

题目比较坑,但可以AC.

首先这两个人并不都是从宿舍到实验室,所以要分情况讨论.

然后很容易想到取出两者公共最短路上的边,然后找最长路,注意这里有一点技巧

首先新图中存在环,不能用一般方法,我们就把边弄成单向边,就十分简单了,直接拓扑排序或记忆化搜索就可以弄出答案了.

具体方法就是我们强制规定边的方向,如从 \(x1->y1\) 最后做两边即可

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <cmath>
#define RG register
#define il inline
#define iter iterator
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
const int N=1505;
int head[N],nxt[N*N],to[N*N],num=1,n,m,dis[N*N],S1,S2,T1,T2;
void link(int x,int y,int z){
nxt[++num]=head[x];to[num]=y;head[x]=num;dis[num]=z;}
int f[5][N],mod=N*10,q[N*10];bool vis[N],mark[N];
void spfa(int STA,int t){
memset(f[t],127/3,sizeof(f[t]));
memset(vis,0,sizeof(vis));
int x,u,tail=0,sum=1;q[1]=STA;vis[STA]=1;f[t][STA]=0;
while(tail!=sum){
tail++;if(tail==mod)tail=0;x=q[tail];
for(int i=head[x];i;i=nxt[i]){
u=to[i];
if(f[t][x]+dis[i]<f[t][u]){
f[t][u]=f[t][x]+dis[i];
if(!vis[u]){
vis[u]=true;
sum++;if(sum==mod)sum-=mod;q[sum]=u;
}
}
}
vis[x]=false;
}
}
vector<int>G[2][N];int du[2][N],g[N],ans=0,D[N][N];bool inst[N];
queue<int>que;
void solve(bool t){
int x,u;
memset(g,0,sizeof(g));while(!que.empty())que.pop();
for(int i=1;i<=n;i++)if(!du[t][i] && inst[i])que.push(i),g[i]=0;
while(!que.empty()){
x=que.front();que.pop();ans=Max(ans,g[x]);
for(int i=0,Sz=G[t][x].size();i<Sz;i++){
u=G[t][x][i];du[t][u]--;if(!du[t][u])que.push(u);
g[u]=Max(g[u],g[x]+D[x][u]);
}
}
}
void work()
{
int x,y,z;
scanf("%d%d",&n,&m);
scanf("%d%d%d%d",&S1,&T1,&S2,&T2);
for(int i=1;i<=m;i++){
scanf("%d%d%d",&x,&y,&z);
link(x,y,z);link(y,x,z);
}
spfa(S1,1);spfa(T1,2);spfa(S2,3);spfa(T2,4);
int fr,ti;
for(int i=2;i<=num;i++){
fr=to[i];ti=to[i^1];
if(f[1][fr]+f[2][ti]+dis[i]!=f[1][T1])continue;
if(f[3][fr]+f[4][ti]+dis[i]!=f[3][T2])continue;
G[0][fr].push_back(ti);du[0][ti]++;inst[fr]=inst[ti]=true;
D[fr][ti]=D[ti][fr]=dis[i];
}
solve(0);
memset(inst,0,sizeof(inst));
for(int i=2;i<=num;i++){
fr=to[i];ti=to[i^1];
if(f[1][ti]+f[2][fr]+dis[i]!=f[1][T1])continue;
if(f[3][fr]+f[4][ti]+dis[i]!=f[3][T2])continue;
G[1][ti].push_back(fr);du[1][fr]++;inst[fr]=inst[ti]=true;
D[fr][ti]=D[ti][fr]=dis[i];
}
solve(1);
printf("%d\n",ans);
} int main()
{
work();
return 0;
}

bzoj 1880: [Sdoi2009]Elaxia的路线的更多相关文章

  1. BZOJ 1880: [Sdoi2009]Elaxia的路线( 最短路 + dp )

    找出同时在他们最短路上的边(dijkstra + dfs), 组成新图, 新图DAG的最长路就是答案...因为两人走同一条路但是不同方向也可以, 所以要把一种一个的s,t换一下再更新一次答案 ---- ...

  2. bzoj 1880 [Sdoi2009]Elaxia的路线(最短路+拓扑序)

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

  3. bzoj 1880: [Sdoi2009]Elaxia的路线【spfa+拓扑排序】

    有趣啊 先spfa分别求出以s1,t1,s2,t2为起点的最短路,然后把在s1-->t1或者s2-->t2最短路上的边重新建有向图,跑拓扑最长路即可 #include<iostrea ...

  4. 【BZOJ 1880】 [Sdoi2009]Elaxia的路线 (最短路树)

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

  5. BZOJ1880: [Sdoi2009]Elaxia的路线(最短路)

    1880: [Sdoi2009]Elaxia的路线 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 2049  Solved: 805 题目链接:https ...

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

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

  7. 【BZOJ1880】[Sdoi2009]Elaxia的路线(最短路)

    [BZOJ1880][Sdoi2009]Elaxia的路线(最短路) 题面 BZOJ 洛谷 题解 假装我们知道了任意两点间的最短路,那么我们怎么求解答案呢? 不难发现公共路径一定是一段连续的路径(如果 ...

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

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

  9. 【BZOJ1880】[SDOI2009]Elaxia的路线 (最短路+拓扑排序)

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

随机推荐

  1. Linux下I/O多路转接之select --fd_set

    fd_set 你终于还是来了,能看到这个标题进来的,我想,你一定是和我遇到了一样的问题,一样的疑惑,接下来几个小时,我一定竭尽全力,写出我想说的,希望也正是你所需要的: 关于Linux下I/O多路转接 ...

  2. tableView//collectionView加载时的动画

    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:( ...

  3. Centos7 Yum方式安装Mysql7

    不废话,直奔主题,可以覆盖安装. 下载并安装MySQL官方的 Yum Repository [root@localhost ~]# wget -i -c http://dev.mysql.com/ge ...

  4. Gson解析Json数组

    需求:从steam官网获取英雄数据,即为Json数据,并导入到本地数据库 Json数据是这样的 { "result": { "heroes": [ { &quo ...

  5. 创建帧动画1 - xml方式

    废话不多说,先看东西   创建帧动画1 - xml方式 帧动画的创建方式主要以下2种: * 用xml创建动画: * 用代码创建动画:   本文内容主要关注 xml文件 创建帧动画的方式   xml文件 ...

  6. Docker学习笔记 - Docker容器内部署redis

    Docker学习笔记(2-4)Docker应用实验-redist server 和client的安装使用 一.获取redis容器(含客户端和服务端) 二.创建服务端容器 1.在终端A中运行redis- ...

  7. ELK学习总结(1-2)安装ElasticSearch

    1.下载安装      Centos6.4      jdk1.8.20以上 elasticsearch::https://www.elastic.co/downloads/elasticsearch ...

  8. 在Linux的Terminal中显示文本文件特定行的内容

    假设要操纵的文本文件的文件名是 textFile现在想做的事情是在不以编辑模式打开文件的情况下在终端直接提取并输出指定文本文件的指定行的内容 在终端提取指定文本文件的指定行的内容 Tool Comma ...

  9. Java基础语法<六> 数组 Arrays

    笔记整理 来源于<Java核心技术卷 I > <Java编程思想>   允许数组长度为0 new element[0] 数组长度为0与null不同   1. 数组拷贝 允许将一 ...

  10. Java-NIO(六):Channel聚集(gather)写入与分散(scatter)读取

    Channel聚集(gather)写入: 聚集写入( Gathering Writes)是指将多个 Buffer 中的数据“聚集”到 Channel. 特别注意:按照缓冲区的顺序,写入 positio ...