luoguP1186 玛丽卡 x
P1186 玛丽卡
题目描述
麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复。
因为她和他们不住在同一个城市,因此她开始准备她的长途旅行。
在这个国家中每两个城市之间最多只有一条路相通,并且我们知道从一个城市到另一个城市路上所需花费的时间。
麦克在车中无意中听到有一条路正在维修,并且那儿正堵车,但没听清楚到底是哪一条路。无论哪一条路正在维修,从玛丽卡所在的城市都能到达麦克所在的城市。
玛丽卡将只从不堵车的路上通过,并且她将按最短路线行车。麦克希望知道在最糟糕的情况下玛丽卡到达他所在的城市需要多长时间,这样他就能保证他的女朋友离开该城市足够远。
编写程序,帮助麦克找出玛丽卡按最短路线通过不堵车道路到达他所在城市所需的最长时间(用分钟表示)。
输入输出格式
输入格式:
第一行有两个用空格隔开的数N和M,分别表示城市的数量以及城市间道路的数量。1≤N≤1000,1≤M≤N*(N-1)/2。城市用数字1至N标识,麦克在城市1中,玛丽卡在城市N中。
接下来的M行中每行包含三个用空格隔开的数A,B和V。其中1≤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
初读题目,告诉我们,女朋友有风险,耍朋友须谨慎。
如果你还是没有思路,或者是迷迷糊糊。
应该!多读几遍题。
这道题说的是:最短路线里面的最长时间。就是删除一条边,之后找最短路径。
所有找到每一条最短路径里的时间最长的。
每删一条边,都要spfa一边找到最短的路径,之后比较。
算一道很裸的题?不过。这里的难点在语文。要理解!!
帮助麦克找出玛丽卡按->最短路线->通过不堵车道路->到达他所在城市所需的->最长时间
而代码实现,其实就是最开始一遍spfa。用h数组来记录,当前的点在松弛时,最优的那条边。记录边!!!
之后从终点开始,往回找。由于h里有当前节点前面的边。所以可以找到这个图的最短路径。之后呢,删最短路径就是保证最短路的整体还是有就是堵车的时候不能走最短路,最后也要步走这条边也要找到最短路。而且找的时候专除小的边。
1)会T一个点
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct node
{
int next,v,t,val;
} edge[];
int heads[],d[],cnt,head,last,visit[],h[];
int q[];//手写队列
int n,m;
int add(int x,int y,int z) //领接表,里面有起点!这个重要。
{
edge[++cnt].next=heads[x];
edge[cnt].v=y;
edge[cnt].t=x;
edge[cnt].val=z;
heads[x]=cnt;
}
int spfa(int x)
{
memset(d,0x7f,sizeof(d));
d[]=;
int t=edge[x].val;
edge[x].val=0xffff;//删边
head=;
last=;
q[last]=;
visit[]=;
while(head<=last)
{
int a=q[head];
for(int i=heads[a]; i!=-; i=edge[i].next)
{
if(d[edge[i].v]>d[a]+edge[i].val)
{
if(!visit[edge[i].v])
{
q[++last]=edge[i].v;
visit[edge[i].v]=;
d[edge[i].v]=d[a]+edge[i].val;
}
else
{
d[edge[i].v]=d[a]+edge[i].val;
}
}
}
head++;
visit[a]=;
}
edge[x].val=t;
}
int main()
{
memset(d,,sizeof(d));
memset(heads,-,sizeof(heads));
int x,y,z;
scanf("%d%d",&n,&m);
for(int i=; i<=m; i++)
{
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
head=;
last=;
q[last]=;
visit[]=;
d[]=;
while(head<=last)
{
int a=q[head];
for(int i=heads[a]; i!=-; i=edge[i].next)
{
if(d[edge[i].v]>d[a]+edge[i].val)
{
if(!visit[edge[i].v])
{
q[++last]=edge[i].v;
visit[edge[i].v]=;
d[edge[i].v]=d[a]+edge[i].val;
h[edge[i].v]=i; //记录每个点最短路松弛时的边
}
else
{
d[edge[i].v]=d[a]+edge[i].val;
h[edge[i].v]=i;//同上
}
}
}
head++;
visit[a]=;
}
int b=d[n];
for(int i=n; i!=; i=edge[h[i]].t) //枚举从终点一直到起点,删最短路的一条边。
{
spfa(h[i]);
b=max(b,d[n]);
}
printf("%d",b);
return ;
}
2)AC
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue> using namespace std;
const int D = ;
const int S = 1e6 + ;
const int M = 2e6; struct orz
{
int next,v,t,val;
} edge[S]; int heads[S],d[D],cnt;
int v[D],h[D];
int n,m;
bool cannot[M]; inline long long read()
{
int x=,f=;
char ch=getchar();
while(ch<'' || ch>''){ if(ch=='-') f=-;ch=getchar();}
while(ch>='' && ch<=''){ x=x*+ch-''; ch=getchar();}
return x*f;
} int add(int x,int y,int z) ///邻接表,里面有起点!这个重要.
{
edge[++cnt].next=heads[x];
edge[cnt].t=x;
edge[cnt].v=y;
edge[cnt].val=z;
heads[x]=cnt;
} int spfa(bool flag)
{
memset(d,0x7f7f7f,sizeof(d));
memset(v,,sizeof(v));
queue<int>q;
q.push();
v[]=;
d[]=;///麦克起点为1
while(!q.empty())
{
int a=q.front();
q.pop();
v[a]=;
for(int i=heads[a]; i!=-; i=edge[i].next)
{
int vv=edge[i].v,val=edge[i].val;
if(cannot[a*+vv]) continue;
if(d[vv]>d[a]+val)
{
d[vv]=d[a]+val;
if(flag) h[vv]=a;
if(!v[vv])
{
q.push(vv);
v[vv]=;
}
}
}
}
} int main()
{
memset(heads,-,sizeof(heads));
int a,b,c;
n=read();m=read();
for(int i=;i<=m;i++)
{
a=read(),b=read(),c=read();
add(a,b,c),add(b,a,c);
}
spfa();
int ans=d[n];
int y=n;
while(y)
{
cannot[y*+h[y]]=;
cannot[h[y]*+y]=;
spfa();
if(d[n]>ans) ans=d[n];
cannot[y*+h[y]]=;
cannot[h[y]*+y]=;
y=h[y];
}
printf("%d\n",ans);
return ;
}
luoguP1186 玛丽卡 x的更多相关文章
- [luoguP1186] 玛丽卡(spfa)
传送门 因为要随机删除一条边,而枚举所有边肯定会超时,经过发现,先求出一遍最短路,而要删除的边肯定在最短路径上,删除其他的边对最短路没有影响. 所以可以先求出最短路,再枚举删除最短路上的每一条边再求最 ...
- codevs 1021 玛丽卡(spfa)
题目描述 Description 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. 因为她和他们不住在同一个城市,因此她开始准备她的长途旅行. 在这个国家中每两个城市之间最多只有一条路相通,并且我们 ...
- codevs1021 玛丽卡
题目描述 Description 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. 因为她和他们不住在同一个城市,因此她开始准备她的长途旅行. 在这个国家中每两个城市之间最多只有一条路相通,并且我们 ...
- Codevs 1021 (玛丽卡)
题目描述 Description 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. 因为她和他们不住在同一个城市,因此她开始准备她的长途旅行. 在这个国家中每两个城市之间最多只有一条路相通,并且我们 ...
- Code[VS]1021 玛丽卡题解
Code[VS]1021 玛丽卡题解 SPFA Algorithm 题目传送门:http://codevs.cn/problem/1021/ 题目描述 Description 麦克找了个新女朋友,玛丽 ...
- Codevs 1021 玛丽卡
Codevs 1021 玛丽卡 题目地址:http://codevs.cn/problem/1021/ 题目描述 Description 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. 因为她和他 ...
- 1021 玛丽卡 - Wikioi
题目描述 Description麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. 因为她和他们不住在同一个城市,因此她开始准备她的长途旅行. 在这个国家中每两个城市之间最多只有一条路相通,并且我们知 ...
- #图# #SPFA# ----- codevs1021 玛丽卡
codevs1021 玛丽卡 题目描述 Description麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复.因为她和他们不住在同一个城市,因此她开始准备她的长途旅行.在这个国家中每两个城市之间最多 ...
- P1186 玛丽卡
题目描述 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. 因为她和他们不住在同一个城市,因此她开始准备她的长途旅行. 在这个国家中每两个城市之间最多只有一条路相通,并且我们知道从一个城市到另一个城 ...
随机推荐
- TCP网络编程(Socket通讯)
TCP 网路编程: 1.TCP 三次握手: 第一次握手,客户端向服务器端发出连接请求,等待服务器确认. 第二次握手,服务器端向客户端回送一个响应,通知客户端收到了连接请求. 第三次握手,客户端再次向服 ...
- spark MLlib矩阵四则运算,线性代数
1.导包请看我的上一篇博文,maven项目的包 https://www.cnblogs.com/wuzaipei/p/10965680.html 2.denseMatirx 矩阵四则运算如下 版本不同 ...
- TestNG+extentReports+log4j2 完善自动化测试框架——美观的报告和保留日志文件
1:导入Maven依赖<dependency> <groupId>com.aventstack</groupId> <artifactId>extent ...
- 20191112 Spring Boot官方文档学习(4.4)
4.4.日志 Spring Boot使用Commons Logging进行所有内部日志记录,但是使底层日志实现打开状态.为Java Util Logging,Log4J2和Logback提供了默认配置 ...
- postfix无法启动问题
open /etc/postfix/main.cf comment out inet_interfaces: all add inet_protocol: ipv4
- [19/06/06-星期四] HTML基础_文本标签、列表(有序、无序、定义)、文本格式化(单位、字体、大小写、文本修饰、间距、对齐文本)
一.文本标签 em:用来表示一段内容的着重点,语气上的强调.一般显示为斜体 i:是斜体显示,和em显示效果一样.h5规定不需要着重的内容而是单纯加粗或斜体可以用i或b.用的不多 strong:用来表示 ...
- Python 入门之 Python三大器 之 生成器
Python 入门之 Python三大器 之 生成器 1.生成器 (1)什么是生成器? 核心:生成器的本质就是一个迭代器 迭代器是Python自带的 生成器程序员自己写的一种迭代器 def func( ...
- Windows下spark1.6.0本地环境搭建
由于spark是用scala编写的,且需要jdk的环境支撑,所以本地spark环境的搭建需要四个步骤:JDK的安装,scala的安装,hadoop的配置,spark的配置. 一.jdk的安装与环境变量 ...
- set(详解)
1.关于set C++ STL 之所以得到广泛的赞誉,也被很多人使用,不只是提供了像vector, string, list等方便的容器,更重要的是STL封装了许多复杂的数据结构算法和大量常用数据结构 ...
- HTML DOM中的comfirm()确认对话框
前言 最近在开发中有一个需求大概就是说:表单点击提交按钮首先弹出确认对话框,然后点击确定请求接口,那么问题来了,我们如何确定点击的是确定还是取消呢? 定义和用法 定义 comfirm()确认对话框,用 ...