洛谷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的序 ...
随机推荐
- ubuntu软件工具推荐
时间:2019-04-11 记录:PangYuaner 标题:串口调试利器--Minicom配置及使用详解 地址:https://www.cnblogs.com/wonux/p/5897127.htm ...
- 剑指 Offer 33. 二叉搜索树的后序遍历序列
剑指 Offer 33. 二叉搜索树的后序遍历序列 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果.如果是则返回 true,否则返回 false.假设输入的数组的任意两个数字都互不相同. ...
- GoLang设计模式02 - 工厂模式
工厂模式是一种创建型模式,也是最常用的设计模式之一.调用方通过工厂产出并获取对象,可以不必关注对象创建的细节和构建逻辑. 在工厂模式下,调用方只和工厂进行交互,并告诉工厂具体获取哪种类型的对象.工厂负 ...
- 使用vbs调用excel中的宏
使用vbs打开excel文件,并且传递参数调用excel中的macro,自动化完成excel文件的制作. Set oExcel = createobject("Excel.Applicati ...
- 剑指 Offer 31. 栈的压入、弹出序列
剑指 Offer 31. 栈的压入.弹出序列 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如,序列 {1,2,3,4,5} 是某 ...
- 【进阶之路】持续集成、持续交付与持续部署(CI/CD)
由来 记得7月份刚刚换工作的时候,中午和老大一起去吃饭,回来的路上老大问我:"南橘,CI/CD有没有研究过?" 我隐隐约约在哪里听过这个名词,但是又想不起来,秉着实事求是的态度,我 ...
- [Elasticsearch] ES更新问题踩坑记录
问题描述 我们有个系统设计的时候针对Hive创建表.删除表, 需要更新ES中的一个状态,标记是否删除,在几乎同时执行两条下面的语句的时候,发现在ES 中出现表即使被创建了还是无法被查询到的情况,针对该 ...
- [考试总结]noip模拟40
最近真的是爆炸啊... 到现在还是有不少没改出来.... 所以先写一下 \(T1\) 的题解.... 送花 我们移动右端点,之后我们用线段树维护全局最大值. 之后还要记录上次的位置和上上次的位置. 之 ...
- Weblogic Coherence组件漏洞初探CVE-2020-2555
Weblogic Coherence组件漏洞初探CVE-2020-2555 2020年1月,互联网上爆出了weblogic反序列化远程命令执行漏洞(CVE-2020-2555),Oracle Fusi ...
- 第一次用AngularJS
1.创建指令的4种方式(ECMA) var appModule = angular.module('app', []); appModule.directive('hello', function() ...