P1186 玛丽卡
题目描述
麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复。
因为她和他们不住在同一个城市,因此她开始准备她的长途旅行。
在这个国家中每两个城市之间最多只有一条路相通,并且我们知道从一个城市到另一个城市路上所需花费的时间。
麦克在车中无意中听到有一条路正在维修,并且那儿正堵车,但没听清楚到底是哪一条路。无论哪一条路正在维修,从玛丽卡所在的城市都能到达麦克所在的城市。
玛丽卡将只从不堵车的路上通过,并且她将按最短路线行车。麦克希望知道在最糟糕的情况下玛丽卡到达他所在的城市需要多长时间,这样他就能保证他的女朋友离开该城市足够远。
编写程序,帮助麦克找出玛丽卡按最短路线通过不堵车道路到达他所在城市所需的最长时间(用分钟表示)。
输入输出格式
输入格式:
第一行有两个用空格隔开的数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分钟内就能通过。
输出格式:
一行,写出用分钟表示的最长时间,在这段时间中,无论哪条路在堵车,玛丽卡应该能够到达麦克处,如果少于这个时间的话,则必定存在一条路,该条路一旦堵车,玛丽卡就不能够赶到麦克处。
输入输出样例
5 7
1 2 8
1 4 10
2 3 9
2 4 10
2 5 1
3 4 7
3 5 10
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 玛丽卡的更多相关文章
- 洛谷P1186 玛丽卡 spfa+删边
洛谷P1186 玛丽卡http://blog.csdn.net/huihao123456/article/details/73414139题目描述 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. ...
- 洛谷——P1186 玛丽卡
P1186 玛丽卡 题目描述 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. 因为她和他们不住在同一个城市,因此她开始准备她的长途旅行. 在这个国家中每两个城市之间最多只有一条路相通,并且我们知道 ...
- 洛谷 P1186 玛丽卡
P1186 玛丽卡 题目描述 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. 因为她和他们不住在同一个城市,因此她开始准备她的长途旅行. 在这个国家中每两个城市之间最多只有一条路相通,并且我们知道 ...
- luogu P1186 玛丽卡
题目描述 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. 因为她和他们不住在同一个城市,因此她开始准备她的长途旅行. 在这个国家中每两个城市之间最多只有一条路相通,并且我们知道从一个城市到另一个城 ...
- 洛谷—— P1186 玛丽卡
https://www.luogu.org/problem/show?pid=1186 题目描述 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. 因为她和他们不住在同一个城市,因此她开始准备她的长 ...
- Luogu P1186 玛丽卡 【最短路】By cellur925
题目描述 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. 因为她和他们不住在同一个城市,因此她开始准备她的长途旅行. 在这个国家中每两个城市之间最多只有一条路相通,并且我们知道从一个城市到另一个城 ...
- 洛谷P1186 玛丽卡
题目描述 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. 因为她和他们不住在同一个城市,因此她开始准备她的长途旅行. 在这个国家中每两个城市之间最多只有一条路相通,并且我们知道从一个城市到另一个城 ...
- 洛谷P1186玛丽卡
传送门啦 先跑一遍最短路,将最短路的路径记录下来,然后枚举每一条最短路的边,将其断掉,记录此时的1-n的时间,取其中最大的一个时间即为所求. (通过 $ cut[][] $ 和 $ f[] $ 进行操 ...
- 【luogu P1186 玛丽卡】 题解
题目链接:https://www.luogu.org/problemnew/show/P1186 邻接表开大开小真的奇妙,毒瘤玩意,再您妈的见. #include <queue> #inc ...
随机推荐
- win10,vs2017+mpi v10.0 安装与入门 (详细)
一.安装visual studio 2017 下载 地址:https://visualstudio.microsoft.com/zh-hans/vs/ 安装 我们再选择自己想要安装的东西,确认好后点 ...
- # Do—Now——团队冲刺博客_总结篇
Do-Now--团队冲刺博客_总结篇 目录 博客链接 作者 1. 第一篇(领航篇) @仇夏 2. 第二篇 @侯泽洋 3. 第三篇 @仇夏 4. 第四篇 @周亚杰 5. 第五篇 @唐才铭 6. 第六篇 ...
- javase 基本运算符和三大流程
范围:-(2 ^ 字节 X 8 - 1)~(2 ^ 字节 X 8 - 1)- 1 主要区别是数据大小范围: 1. byte 一个字节 -128 ~ 127 2. short 两个 ...
- TypeScript -访问修饰符
class test extends egret.DisplayObjectContainer { public constructor() { /** * 1.不添加构造函数constructor ...
- C++调用C语言的库函数
在项目中,使用C语言编写了一个socket后台程序tkcofferd,并且为方便客户端的使用,提供了动态库,其中包含socket接口. 现在的需求是使用qt做一个前端界面,用来展示tkcofferd的 ...
- document.querySelectorAll() 兼容 IE6
不多说,直接上代码 // 使用 css 选择器获取元素对象 兼容性封装 Test Already. function getElementsByCss(cssStr){ if(document.que ...
- 一个bat病毒分析(part1)
之前没学过bat,这里借分析顺便学一波,分析过程可能有点啰嗦 这里的@echo off关闭回显,病毒一般都是隐秘的执行的,然后setlocal enabledelayedexpansion是设置本地变 ...
- nodejs----微信注册测试号获取token
var PORT=8081; //监听8080端口号 var http=require('http'); var qs=require('qs'); var TOKEN='yezhenxu'; //必 ...
- n&m位运算
在C/C++语言里,&代表取地址或者“位与”运算 1.取变量的地址:&变量名,这将获得该变量的地址,例:int a = 1, &p = a. 2.进行位与运算,格式是:变量1& ...
- JVM深入:JVM内存堆布局图解分析(转)
转载自:https://www.cnblogs.com/SaraMoring/p/5713732.html 原文:http://www.codeceo.com/article/jvm-memory-s ...