P3106 [USACO14OPEN]GPS的决斗(最短路)

化简:够简的了.....但是!翻译绝对有锅。
这个最短路是从n到每个点的单源最短路,也就是最短路径树。
那么,思路就很明确了。建两个图,然后跑两边SPFA,记录下最短路径。
然后,对于两点之间的边,如果最短路不经过它,那么最终图边权+1;
然后在最终图上(边权为0,1,2)跑一遍SPFA即可。
一开始我想复杂了,在想怎么记录路径,怎么重构图.balabala。
然后发现,怎么才能让两点不在最短路径上呢?
SPFA的松弛操作,依据是三角不等式。于是,如果两点之间的最短路的距离如果不等于边权(也就是最短路径不过它俩之间的边)那么就它就是一条会报警的边。
$$看来SPFA最重要的是三角不等式$$
于是,只要暴力跑三遍SPFA即可。
用尽浑身解数,信仰SPFA,各种常数优化,读入挂,我还是没能跑到最优解的第一面....在第二页前几个徘徊.....
代码:(这么长的图论题也不多见,但是好像逛公园就那么长)
#include<iostream>
#include<cstdio>
#include<queue>
#define rg register
using namespace std;
const int maxn=1e6+;
int n,m;
inline int read()
{
int x=,f=;char s=getchar();
while(s>''||s<''){if(s=='-')f=-;s=getchar();}
while(s<=''&&s>=''){x=x*+s-'';s=getchar();}
return x*f;
}
struct edge
{
int to,next,dis;
}e1[maxn],e2[maxn],e[maxn];
int head[maxn],head1[maxn],head2[maxn];
int cnt1,cnt2,cnt;
inline void addedge1(int from,int to,int dis)
{
e1[++cnt1].next=head1[from];
e1[cnt1].to=to;
e1[cnt1].dis=dis;
head1[from]=cnt1;
}
inline void addedge2(int from,int to,int dis)
{
e2[++cnt2].next=head2[from];
e2[cnt2].to=to;
e2[cnt2].dis=dis;
head2[from]=cnt2;
}
inline void addedge(int from,int to,int dis)
{
e[++cnt].next=head[from];
e[cnt].to=to;
e[cnt].dis=dis;
head[from]=cnt;
} int dis1[maxn],vis1[maxn],pre1[maxn];
struct cmp1
{
bool operator () (int a,int b)
{
return dis1[a]>dis1[b];
}
};
inline void spfa1()
{
priority_queue < int , vector < int > , cmp1 > q;
for(rg int i=;i<=n;i++)
{
dis1[i]=;
vis1[i]=;
}
q.push(n);
dis1[n]=;
vis1[n]=;
while(!q.empty())
{
int u=q.top();
q.pop();
vis1[u]=;
for(rg int i=head1[u];i;i=e1[i].next)
{
int v=e1[i].to;
if(dis1[v]>dis1[u]+e1[i].dis)
{
dis1[v]=dis1[u]+e1[i].dis;
if(vis1[v]==)
{
vis1[v]=;
q.push(v);
}
}
}
}
}
int dis2[maxn],vis2[maxn],pre2[maxn];
struct cmp2
{
bool operator () (int a,int b)
{
return dis2[a]>dis2[b];
}
};
inline void spfa2()
{
priority_queue < int , vector < int > , cmp2 > q;
for(rg int i=;i<=n;i++)
{
dis2[i]=;
vis2[i]=;
}
q.push(n);
dis2[n]=;
vis2[n]=;
while(!q.empty())
{
int u=q.top();
q.pop();
vis2[u]=;
for(rg int i=head2[u];i;i=e2[i].next)
{
int v=e2[i].to;
if(dis2[v]>dis2[u]+e2[i].dis)
{
dis2[v]=dis2[u]+e2[i].dis;
if(vis2[v]==)
{
vis2[v]=;
q.push(v);
}
}
}
}
}
int dis[maxn],vis[maxn];
struct cmp
{
bool operator () (int a,int b)
{
return dis[a]>dis[b];
}
};
inline void rebuild()
{
for(rg int i=;i<=n;i++)
{
for(int j=head1[i];j;j=e1[j].next)
{
int v1=e1[j].to;
int v2=e2[j].to;
//cout<<i<<' '<<v1<<endl;
int d=;
if(dis1[v1]-dis1[i]!=e1[j].dis)
d++;
if(dis2[v2]-dis2[i]!=e2[j].dis)
d++;
addedge(v1,i,d);
}
}
}
inline void spfa()
{
priority_queue < int , vector < int > , cmp > q;
for(rg int i=;i<=n;i++)
{
dis[i]=;
vis[i]=;
}
q.push();
dis[]=;
vis[]=;
while(!q.empty())
{
int u=q.top();
q.pop();
vis[u]=;
for(rg int i=head[u];i;i=e[i].next)
{
int v=e[i].to;
if(dis[v]>dis[u]+e[i].dis)
{
dis[v]=dis[u]+e[i].dis;
if(vis[v]==)
{
vis[v]=;
q.push(v);
}
}
}
}
}
int main()
{
n=read();
m=read();
for(rg int i=;i<=m;i++)
{
int a=read(),b=read(),c=read(),d=read();
//scanf("%d%d%d%d",&a,&b,&c,&d);
addedge1(b,a,c);
addedge2(b,a,d);
//addedge(a,b,0);
}
spfa1();
spfa2();
rebuild();
spfa();
printf("%d",dis[n]);
return ;
}
(完)
P3106 [USACO14OPEN]GPS的决斗(最短路)的更多相关文章
- Luogu P3106 [USACO14OPEN]GPS的决斗Dueling GPS's(最短路)
P3106 [USACO14OPEN]GPS的决斗Dueling GPS's 题意 题目描述 Farmer John has recently purchased a new car online, ...
- BZOJ 3538 == 洛谷 P3106 [USACO14OPEN]GPS的决斗Dueling GPS's
P3106 [USACO14OPEN]GPS的决斗Dueling GPS's 题目描述 Farmer John has recently purchased a new car online, but ...
- [USACO14OPEN]GPS的决斗Dueling GPS's
题目概况 题目描述 给你一个\(N\)个点的有向图,可能有重边. 有两个\(GPS\)定位系统,分别认为经过边\(i\)的时间为\(P_i\),和\(Q_i\). 每走一条边的时候,如果一个系统认为走 ...
- 洛谷 3106 [USACO14OPEN]GPS的决斗Dueling GPS's 3720 [AHOI2017初中组]guide
[题解] 这两道题是完全一样的. 思路其实很简单,对于两种边权分别建反向图跑dijkstra. 如果某条边在某一种边权的图中不是最短路上的边,就把它的cnt加上1.(这样每条边的cnt是0或1或2,代 ...
- 2018.07.22 洛谷P3106 GPS的决斗Dueling GPS's(最短路)
传送门 图论模拟题. 这题直接写3个(可以压成一个)spfa" role="presentation" style="position: relative;&q ...
- USACO Dueling GPS's
洛谷 P3106 [USACO14OPEN]GPS的决斗Dueling GPS's 洛谷传送门 JDOJ 2424: USACO 2014 Open Silver 2.Dueling GPSs JDO ...
- CSP-S 2019图论总结
CSP-S 2019图论总结 一.最短路问题 模板 Floyd算法 void floyd() { memset(map,0x3f,sizeof(map)); for(int i=1;i<=n;i ...
- [USACO14OPEN] Dueling GPS's[最短路建模]
题目描述 Farmer John has recently purchased a new car online, but in his haste he accidentally clicked t ...
- [BZOJ3538]坑爹的GPS
题目描述 Description 有一天,\(FJ\) 买了一辆车,但是,他一手下载了两个\(GPS\) 系统.好了现在麻烦的事情来了,\(GPS\) 有一个功能大概大家也知道,如果\(FJ\) 没有 ...
随机推荐
- golang面试题--string操作
题目: 请实现一个算法,确定一个字符串的所有字符[是否全都不同].这里我们要求[不允许使用额外的存储结构].给定一个string,请返回一个bool值,true代表所有字符全都不同,false代表存在 ...
- Android开发——RecyclerView实现下载列表
本篇记录的是使用Jsoup框架爬取网页内容,结合Android的RecyclerView,从而实现批量下载小说的功能(也是我的APP星之小说下载器Android版的核心功能),思路仅供参考 本文使用了 ...
- 从干将莫邪的故事说起--java比较操作注意要点
故事背景 <搜神记>: 楚干将.莫邪为楚王作剑,三年乃成.王怒,欲杀之.剑有雌雄.其妻重身当产.夫语妻曰:“吾为王作剑,三年乃成.王怒,往必杀我.汝若生子是男,大,告之曰:‘出户望南山,松 ...
- Requests实践详解
Requests是什么 Requests是用python语言基于urllib编写的,采用的是Apache2 Licensed开源协议的HTTP库 如果你看过上篇文章关于urllib库的使用,你会发现, ...
- Cocos Creator 通用框架设计 —— 网络
在Creator中发起一个http请求是比较简单的,但很多游戏希望能够和服务器之间保持长连接,以便服务端能够主动向客户端推送消息,而非总是由客户端发起请求,对于实时性要求较高的游戏更是如此.这里我们会 ...
- 洛谷 P3833 [SHOI2012]魔法树
题目背景 SHOI2012 D2T3 题目描述 Harry Potter 新学了一种魔法:可以让改变树上的果子个数.满心欢喜的他找到了一个巨大的果树,来试验他的新法术. 这棵果树共有N个节点,其中节点 ...
- Redis 复制过程详解
Redis 的复制功能分为同步( sync )和命令传播( command propagate )两个步骤: 同步用于将从服务器的数据库状态更新至主服务器当前所处的数据库状态. 命令传播则用于在主服务 ...
- 移动端Rem布局注意事项
1.布局的总体结构框架: 2.注意事项: (a):如果是左右两栏的布局方式,须在article的同级加一个aside: 因为是同级,所以必须设置同样的样式:而且他俩的父级,也就是sectio ...
- Hadoop实战1:MapR在ubuntu集群中的安装
由于机器学习算法在处理大数据处理的时候在所难免的会效率降低,公司需要搭建hadoop集群,最后采用了商业版的Hadoop2(MapR). 官网: http://doc.mapr.com/display ...
- jquery的返回顶端的功能实现
页面很长的时候,读到最下面,需要返回顶端,则在页面最下面布局一个返回顶部的图标很有用. 具体功能是,jquey控制,向下滚动出现返回顶部图片,若滚动返回顶部或点回顶部,则图标消失. 实现效果如下图: