洛谷2149 Elaxia的路线(dp+最短路)
QwQ好久没更新博客了,颓废了好久啊,来补一点东西
题目大意
给定两个点对,求两对点间最短路的最长公共路径。
其中\(n,m\le 10^5\)
比较简单吧
就是跑四遍最短路,然后把最短路上的边拿出来,跑一遍拓扑排序加\(dp\)就OK
对于一条边\(u->v\),满足\(dis[u]+w+disn[v]=dis[t]\)那么这条边就是最短路上的边,其中\(disn[x]\)表示\(t\)到\(x\)的最短路,\(dis[x]\)表示\(s\)到\(x\)的最短路
直接上代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#define pa pair<int,int>
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
const int maxn = 7010;
const int maxm = 2e6+1e2;
int point[maxn],nxt[maxm],to[maxm],val[maxm];
int dis[maxn];
int disn[maxn];
int dis1[maxn];
int disn1[maxn];
int vis[maxn];
int n,m,cnt;
int x[maxm],y[maxm],w[maxm];
int dp[maxn];
int s1,t1,s2,t2;
priority_queue<pa,vector<pa>,greater<pa> > q;
void addedge(int x,int y,int w)
{
nxt[++cnt]=point[x];
to[cnt]=y;
val[cnt]=w;
point[x]=cnt;
}
void dijkstra(int s)
{
memset(vis,0,sizeof(vis));
memset(dis,127/3,sizeof(dis));
dis[s]=0;
q.push(make_pair(0,s));
while (!q.empty())
{
int x = q.top().second;
q.pop();
if (vis[x]) continue;
vis[x]=1;
for (int i=point[x];i;i=nxt[i])
{
int p = to[i];
if (dis[p]>dis[x]+val[i])
{
dis[p]=dis[x]+val[i];
q.push(make_pair(dis[p],p));
}
}
}
}
void dijkstra1(int s)
{
memset(vis,0,sizeof(vis));
memset(disn,127/3,sizeof(disn));
disn[s]=0;
q.push(make_pair(0,s));
while (!q.empty())
{
int x = q.top().second;
q.pop();
if (vis[x]) continue;
vis[x]=1;
for (int i=point[x];i;i=nxt[i])
{
int p = to[i];
if (disn[p]>disn[x]+val[i])
{
disn[p]=disn[x]+val[i];
q.push(make_pair(disn[p],p));
}
}
}
}
void dijkstra2(int s)
{
memset(vis,0,sizeof(vis));
memset(dis1,127/3,sizeof(dis1));
dis1[s]=0;
q.push(make_pair(0,s));
while (!q.empty())
{
int x = q.top().second;
q.pop();
if (vis[x]) continue;
vis[x]=1;
for (int i=point[x];i;i=nxt[i])
{
int p = to[i];
if (dis1[p]>dis1[x]+val[i])
{
dis1[p]=dis1[x]+val[i];
q.push(make_pair(dis1[p],p));
}
}
}
}
void dijkstra3(int s)
{
memset(vis,0,sizeof(vis));
memset(disn1,127/3,sizeof(disn1));
disn1[s]=0;
q.push(make_pair(0,s));
while (!q.empty())
{
int x = q.top().second;
q.pop();
if (vis[x]) continue;
vis[x]=1;
for (int i=point[x];i;i=nxt[i])
{
int p = to[i];
if (disn1[p]>disn1[x]+val[i])
{
disn1[p]=disn1[x]+val[i];
q.push(make_pair(disn1[p],p));
}
}
}
}
int tmp = 0;
int num[maxm];
int ymh[maxm];
int in[maxn];
queue<int> que;
int a[2100][2100];
int main()
{
memset(a,-1,sizeof(a));
n=read(),m=read();
s1=read(),t1=read();
s2=read(),t2=read();
for (int i=1;i<=m;i++){
int u,v,ww;
u=read(),v=read(),ww=read();
addedge(u,v,ww);
addedge(v,u,ww);
x[++tmp]=u;
y[tmp]=v;
w[tmp]=ww;
x[++tmp]=v;
y[tmp]=u;
w[tmp]=ww;
}
dijkstra(s1);
dijkstra1(t1);
dijkstra2(s2);
dijkstra3(t2);
memset(point,0,sizeof(point));
cnt=0;
for (int i=1;i<=tmp;i++)
{
if (dis[x[i]]+w[i]+disn[y[i]]==dis[t1]) addedge(x[i],y[i],w[i]),num[i]=1,in[y[i]]++,a[x[i]][y[i]]++,a[y[i]][x[i]]++;
}
for (int i=1;i<=tmp;i++)
{
if (dis1[x[i]]+w[i]+disn1[y[i]]==dis1[t2]) {a[x[i]][y[i]]++,a[y[i]][x[i]]++;}
}
for (int i=1;i<=n;i++) if (!in[i]) que.push(i);
while (!que.empty())
{
int x = que.front();
que.pop();
for (int i=point[x];i;i=nxt[i])
{
int p = to[i];
//cout<<x<<" "<<p<<" "<<a[x][p]<<endl;
dp[p]=max(dp[p],dp[x]+a[x][p]*val[i]);
in[p]--;
if (!in[p]) que.push(p);
}
}
int ans=-1e9;
for (int i=1;i<=n;i++) ans=max(ans,dp[i]);
cout<<ans;
return 0;
}
洛谷2149 Elaxia的路线(dp+最短路)的更多相关文章
- 洛谷P2149 Elaxia的路线
传送门啦 分析: 我最开始想的是跑两遍最短路,然后记录一下最短路走了哪些边(如果有两条最短路就选经过边多的),打上标记.两边之后找两次都标记的边有多少就行了. 但...我并没有实现出来. 最后让我们看 ...
- 洛谷 P1613 跑路 (倍增 + DP + 最短路)
题目链接:P1613 跑路 题意 给定包含 \(n\) 个点和 \(m\) 条边的有向图,每条边的长度为 \(1\) 千米.每秒钟可以跑 \(2^k\) 千米,问从点 \(1\) 到点 \(n\) 最 ...
- 洛谷 P4478 [BJWC2018]上学路线
洛谷 P4478 [BJWC2018]上学路线 原题 神仙题orz,竟然没有1A....容斥+卢卡斯+crt?? 首先用容斥做,记\(f[i][0/1]\)表示到i号点经过了奇数/偶数个点的方案数,因 ...
- 洛谷 P5279 - [ZJOI2019]麻将(dp 套 dp)
洛谷题面传送门 一道 dp 套 dp 的 immortal tea 首先考虑如何判断一套牌是否已经胡牌了,考虑 \(dp\).我们考虑将所有牌按权值大小从大到小排成一列,那我们设 \(dp_ ...
- 【BZOJ1880】[Sdoi2009]Elaxia的路线(最短路)
[BZOJ1880][Sdoi2009]Elaxia的路线(最短路) 题面 BZOJ 洛谷 题解 假装我们知道了任意两点间的最短路,那么我们怎么求解答案呢? 不难发现公共路径一定是一段连续的路径(如果 ...
- BZOJ1880或洛谷2149 [SDOI2009]Elaxia的路线
BZOJ原题链接 洛谷原题链接 显然最长公共路径是最短路上的一条链. 我们可以把最短路经过的边看成有向边,那么组成的图就是一张\(DAG\),这样题目要求的即是两张\(DAG\)重合部分中的最长链. ...
- Java实现 洛谷 Car的旅行路线
输入输出样例 输入样例#1: 1 3 10 1 3 1 1 1 3 3 1 30 2 5 7 4 5 2 1 8 6 8 8 11 6 3 输出样例#1: 47.5 import java.util. ...
- 洛谷2344 奶牛抗议(DP+BIT+离散化)
洛谷2344 奶牛抗议 本题地址:http://www.luogu.org/problem/show?pid=2344 题目背景 Generic Cow Protests, 2011 Feb 题目描述 ...
- Lightning Conductor 洛谷P3515 决策单调性优化DP
遇见的第一道决策单调性优化DP,虽然看了题解,但是新技能√,很开森. 先%FlashHu大佬,反正我是看了他的题解和精美的配图才明白的,%%%巨佬. 废话不多说,看题: 题目大意 已知一个长度为n的序 ...
随机推荐
- Mybatis-技术专区-如何清晰的解决出现「多对一模型」和「一对多模型」的问题
前提介绍 在mybatis如何进行多对一.一对多(一对一)的多表查询呢?本章带你认识如何非常顺滑的解决! 基础使用篇 一对一 association association通常用来映射一对一的关系,例 ...
- 源码解析.Net中Middleware的实现
前言 本篇继续之前的思路,不注重用法,如果还不知道有哪些用法的小伙伴,可以点击这里,微软文档说的很详细,在阅读本篇文章前,还是希望你对中间件有大致的了解,这样你读起来可能更加能够意会到意思.废话不多说 ...
- EternalBlue永恒之蓝渗透测试
Eternal Blue(永恒之蓝)-ms17-010渗透测试 第一次做的渗透测试,也是第一次去写博客,还望各位师傅多多指正 :) 工具 1.靶机系统 window7 开放445以及139端口 2.k ...
- JavaWeb中表单数据的获取及乱码问题
首先使用一个用户提交界面作为举例(文本框,密码框,选择,下拉表单等),效果如下 注:HTML < form> 标签的 action 属性,其定义和用法是: 属性值为URL,表示向何处发送表 ...
- Android手机 自动批量发朋友圈
做了各种对比之后,还是这个微商工具最好用
- sed中传递变量进行替换
sed命令中传递变量 例如:修改配置文件某一个变量的值 配置文件如下: toney@ubantu:/mnt/hgfs/em嵌入式学习记录/shell/shell脚本常见用法$ cat common_u ...
- C# Dapper基本三层架构使用 (三、BLL)
BLL层介绍 业务逻辑层用于做一些有效性验证的工作,以更好的保证程序运行的健壮性.如完成数据添加.修改和查询业务等:不允许指定的文本框中输入空字符串,数据格式是否正确以及数据类型验证:用户权限的合法性 ...
- FlinkCDC 2.0使用实践体验
一.背景说明 所谓CDC:全称是 Change Data Capture ,在广义的概念上,只要能捕获数据变更的技术,我们都可以称为 CDC .通常我们说的 CDC 技术主要面向数据库的变更,是一种用 ...
- 用python的pandas读取excel文件中的数据
一.读取Excel文件 使用pandas的read_excel()方法,可通过文件路径直接读取.注意到,在一个excel文件中有多个sheet,因此,对excel文件的读取实际上是读取指定文件.并 ...
- HDU2094产生冠军 (拓扑排序)
HDU2094产生冠军 Description 有一群人,打乒乓球比赛,两两捉对撕杀,每两个人之间最多打一场比赛. 球赛的规则如下: 如果A打败了B,B又打败了C,而A与C之间没有进行过比赛,那么就认 ...