题目描述

麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复。

因为她和他们不住在同一个城市,因此她开始准备她的长途旅行。

在这个国家中每两个城市之间最多只有一条路相通,并且我们知道从一个城市到另一个城市路上所需花费的时间。

麦克在车中无意中听到有一条路正在维修,并且那儿正堵车,但没听清楚到底是哪一条路。无论哪一条路正在维修,从玛丽卡所在的城市都能到达麦克所在的城市。

玛丽卡将只从不堵车的路上通过,并且她将按最短路线行车。麦克希望知道在最糟糕的情况下玛丽卡到达他所在的城市需要多长时间,这样他就能保证他的女朋友离开该城市足够远。

编写程序,帮助麦克找出玛丽卡按最短路线通过不堵车道路到达他所在城市所需的最长时间(用分钟表示)。

输入输出格式

输入格式:

第一行有两个用空格隔开的数NN和MM,分别表示城市的数量以及城市间道路的数量。1≤N≤1000,1≤M≤N (N-1)/2,1≤N≤1000,1≤M≤N×(N−1)/2。城市用数字1-N1−N标识,麦克在城市1中,玛丽卡在城市N中。

接下来的MM行中每行包含三个用空格隔开的数A,B,V,其中1≤A,B≤N,1≤V≤10001≤A,B≤N,1≤V≤1000。这些数字表示在A和城市B中间有一条双行道,并且在V分钟内就能通过。

输出格式:

一行,写出用分钟表示的最长时间,在这段时间中,无论哪条路在堵车,玛丽卡应该能够到达麦克处,如果少于这个时间的话,则必定存在一条路,该条路一旦堵车,玛丽卡就不能够赶到麦克处。

输入输出样例

输入样例#1:

5 7
1 2 8
1 4 10
2 3 9
2 4 10
2 5 1
3 4 7
3 5 10
输出样例#1:

27

解析:

这个题的题目背景真是引人深思,,,我们在集体中要控制好自己的情绪,
在学校中我们要控制好自己,不能与异性过度交往。。。。
好了,废话少说,下面进入正题: 首先我们把这道题的意思理解一下:删除一条边后,最短路的最大值.
自然而然地想到依次屏蔽每一条边,之后求最短路,于是就有了下面这份代码:
 #include<iostream>
#include<cstring>
#include<queue>
#define inf 336860180
using namespace std;
int n,m,k,e,v[],head[],nxt[],w[],dist[],total,b1,b2,b3,d,dp[],No;
bool pd[];
void add(int a,int b,int c)
{
total++;
v[total]=b;
w[total]=c;
nxt[total]=head[a];
head[a]=total;
return;
}
void spfa()
{
memset(dist,,sizeof(dist));
memset(pd,,sizeof(pd));
queue<int>q;
q.push();
dist[]=;
pd[]=;
while(q.size())
{
int x=q.front();
q.pop();
pd[x]=;
for(int i=head[x];i!=-;i=nxt[i])
{
int y=v[i];
if(dist[y]>dist[x]+w[i])
{
dist[y]=dist[x]+w[i];
if(!pd[y])
{
q.push(y);
pd[y]=;
}
}
}
}
}
int main()
{
memset(head,-,sizeof(head));
cin>>n>>m;
for(int i=;i<=m;i++)
{
cin>>b1>>b2>>b3;
add(b1,b2,b3);
add(b2,b1,b3);
}
spfa();
int ans=dist[n];
for(int i=;i<=total;i++)
{
int tmp=w[i];
w[i]=inf+;
spfa();
ans=max(ans,dist[n]);
w[i]=tmp;
}
cout<<ans;
return ;
}
高高兴兴地把这份代码交到测评机上,就会TLE。
会T4个点。
造成这种现象的原因并不是选择了SPFA(SPFA不背锅),而是多次求最短路的结果,
显然这张图是稠密图,最多可以到达数十万条边,而求那么多次最短路,结果只有TLE。
于是我们开始谋求一些改进的方法;
对于这些边,显然我们有许多条是重复计算的,也就是说,屏蔽这些边根本对最短路的结果没有任何影响
我们要屏蔽的,显然是那些不满足三角形不等式的,可以让最短路进行松弛操作的边。
如何把这些边记录下来并进行“屏蔽”操作呢???
我选取的策略是,首先求一次没有屏蔽任何边的最短路,记录下可以进行松弛操作的边,换言之,
就是把可能对最短路有影响的便都记录下来;
同时还要把起点记录下来,开两个数组就行了。
由于我不想搞两个SPFA的函数,更不想打两遍SPFA(即使是复制也不想),所以我搞了个s参数,当这个参数
为1时,表示第一次求最短路,需要在此时记录可以松弛的边和节点,当参数s为0时,表示不是第一次求最短路。就无需进行这个操作了;
下面给出AC代码:

 

 #include<iostream>
#include<cstring>
#include<queue>
#define inf 336860180
using namespace std;
int n,m,k,e,v[],head[],nxt[],w[],dist[],total,b1,b2,b3,nxxt[],point[];
bool pd[];
void add(int a,int b,int c)//邻接表
{
total++;
v[total]=b;
w[total]=c;
nxt[total]=head[a];
head[a]=total;
return;
}
void spfa(int cc,int s)//最短路,s记录是否第一次求最短路
{
memset(dist,,sizeof(dist));
memset(pd,,sizeof(pd));
queue<int>q;
q.push();
dist[]=;
pd[]=;
while(q.size())
{
int x=q.front();
q.pop();
pd[x]=;
for(int i=head[x];i!=-;i=nxt[i])
{
if(i==cc)continue;
int y=v[i];
if(dist[y]>dist[x]+w[i])
{
dist[y]=dist[x]+w[i]; //松弛
if(s)
{
point[y]=i;//记起点
nxxt[y]=x;//记边
}
if(!pd[y])
{
q.push(y);
pd[y]=;
}
}
}
}
}
int main()
{
memset(head,-,sizeof(head));
cin>>n>>m;
for(int i=;i<=m;i++)
{
cin>>b1>>b2>>b3;
add(b1,b2,b3);
add(b2,b1,b3);
}
spfa(,);
int ans=dist[n];
for(int i=n;i;i=nxxt[i])
{
spfa(point[i],);//屏蔽
ans=max(ans,dist[n]);
}
cout<<ans;
return ;
}

最后,祝大家NOIP2019 RP++!!!

这么伟大的题解,不关注+素质三连吗???

P1186 玛丽卡的更多相关文章

  1. 洛谷P1186 玛丽卡 spfa+删边

    洛谷P1186 玛丽卡http://blog.csdn.net/huihao123456/article/details/73414139题目描述 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. ...

  2. 洛谷——P1186 玛丽卡

    P1186 玛丽卡 题目描述 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. 因为她和他们不住在同一个城市,因此她开始准备她的长途旅行. 在这个国家中每两个城市之间最多只有一条路相通,并且我们知道 ...

  3. 洛谷 P1186 玛丽卡

    P1186 玛丽卡 题目描述 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. 因为她和他们不住在同一个城市,因此她开始准备她的长途旅行. 在这个国家中每两个城市之间最多只有一条路相通,并且我们知道 ...

  4. luogu P1186 玛丽卡

    题目描述 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. 因为她和他们不住在同一个城市,因此她开始准备她的长途旅行. 在这个国家中每两个城市之间最多只有一条路相通,并且我们知道从一个城市到另一个城 ...

  5. 洛谷—— P1186 玛丽卡

    https://www.luogu.org/problem/show?pid=1186 题目描述 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. 因为她和他们不住在同一个城市,因此她开始准备她的长 ...

  6. Luogu P1186 玛丽卡 【最短路】By cellur925

    题目描述 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. 因为她和他们不住在同一个城市,因此她开始准备她的长途旅行. 在这个国家中每两个城市之间最多只有一条路相通,并且我们知道从一个城市到另一个城 ...

  7. 洛谷P1186 玛丽卡

    题目描述 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. 因为她和他们不住在同一个城市,因此她开始准备她的长途旅行. 在这个国家中每两个城市之间最多只有一条路相通,并且我们知道从一个城市到另一个城 ...

  8. 洛谷P1186玛丽卡

    传送门啦 先跑一遍最短路,将最短路的路径记录下来,然后枚举每一条最短路的边,将其断掉,记录此时的1-n的时间,取其中最大的一个时间即为所求. (通过 $ cut[][] $ 和 $ f[] $ 进行操 ...

  9. 【luogu P1186 玛丽卡】 题解

    题目链接:https://www.luogu.org/problemnew/show/P1186 邻接表开大开小真的奇妙,毒瘤玩意,再您妈的见. #include <queue> #inc ...

随机推荐

  1. [jzoj]4216.【NOIP2015模拟9.12】平方和

    Link https://jzoj.net/senior/#main/show/4216 Description 给出一个N个整数构成的序列,有M次操作,每次操作有一下三种: ①Insert Y X, ...

  2. d4-01

    一.字典 1.1 var dict = {"name":"zhangsan"}  定义字典 1.2 dict.name     取得name的值 1.3 del ...

  3. C#中异步调用示例与详解

    using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServi ...

  4. Dreamweaver编辑区下方的属性栏显示

    显示属性栏 不小心关闭了Dreamweaver的属性栏,突然用到之后不知道怎么显示,此时需要两步:选择[窗口]工具栏,选择[属性]选项. 此时又可以看到编辑区下方的属性栏了,而且出于编写代码的需要可以 ...

  5. VS2008中 VB 报错 检索 COM 类工厂中 CLSID 为 {28E68F9A-8D75-11D1-8DC3-3C302A000000} 的组件失败,原因是出现以下错误: 80040154 没有注册类 (异常来自 HRESULT:0x80040154 (REGDB_E_CLASSNOTREG))。

    Resvr32 .net中引用控件的名称 如果注册成功,问题不在出现 但是如果是在x64位的系统中,即使控件注册成功,错误依照提示,是因为大多数第三方写的COM控件,只支持32位的系统, 在VS中找到 ...

  6. ElasticSearch + Canal 开发千万级的实时搜索系统

    公司是做社交相关产品的,社交类产品对搜索功能需求要求就比较高,需要根据用户城市.用户ID昵称等进行搜索. 项目原先的搜索接口采用SQL查询的方式实现,数据库表采用了按城市分表的方式.但随着业务的发展, ...

  7. 面试题: 多个 await 处理,有一个失败,就算作失败

    面试题: 多个 await 处理,有一个失败,就算作失败 ? Promise.all([p1, p2, p3....])    // 返回的也是一个 Promise 对象 -------- asait ...

  8. [LeetCode] Design HashMap 设计HashMap

    Design a HashMap without using any built-in hash table libraries. To be specific, your design should ...

  9. [LeetCode] Design Circular Deque 设计环形双向队列

    Design your implementation of the circular double-ended queue (deque). Your implementation should su ...

  10. Centos 7 上使用nginx为Node.js配置反向代理时错误:(13: Permission denied) while connecting to upstream

    错误来源:Centos 7 上使用nginx为Node.js配置反向代理时产生(13: Permission denied) while connecting to upstream的错误 nginx ...