Code[VS]1021 玛丽卡题解

题目描述 Description

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

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

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

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

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

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

输入描述 Input Description

第一行有两个用空格隔开的数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分钟内是就能通过。

输出描述 Output Description

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

样例输入 Sample Input

5 7

1 2 8

1 4 10

2 3 9

2 4 10

2 5 1

3 4 7

3 5 10

样例输出 Sample Output

27


分析

本题求解最短路线通过不堵车道路到达他所在城市所需的最长时间,不难想到,堵车的道路一定要在最短路上才有最大值,否则无论道路在哪都不会影响原来的值。

首先进行一遍SPFA,找出原图中的最短路,并记录路径。再枚举路径上的所有点,删去这条边,再SPFA。一遍遍查找,最终找到最大值。

注释&代码

 #include "bits/stdc++.h"

 using namespace std;
const int maxN = ;
const int INF = ;
struct Edge
{
int from , to , next , w ;
}e[ ]; int n,m,cnt,p[ maxN ],Dis[ maxN ];
int In[ maxN ],pre[ maxN ] ;
bool visited[ maxN ]; void Add_edge(const int x,const int y,const int z)
{
e[ ++cnt ].to = y ;
e[ cnt ].next = p [ x ] ;
e[ cnt ].w = z ;
e[ cnt ].from = x ;
p[ x ] = cnt ;
return ;
} void Spfa ( const int S )
{
int i , t , temp ;
queue <int> Q;
memset ( visited , 0 , sizeof ( visited ) ) ;
memset ( Dis , 0x3f , sizeof ( Dis ) ) ;
memset ( In , 0 , sizeof ( In ) ) ; Q.push( S ) ;
visited[ S ] = true;
Dis[ S ] = 0 ; while( !Q.empty ( ) ) //SPFA找最短路
{
t = Q.front( ) ; Q.pop( ) ; visited [ t ] = false ;
for( i = p[ t ] ; i ; i = e[ i ].next )
{
temp = e[ i ].to;
if ( Dis[ temp ] > Dis[ t ] + e[ i ].w )
{
Dis[ temp ] = Dis[ t ] + e[ i ].w ;
pre [ temp ] = i ; //记录路径
if(!visited[temp])
{
Q.push(temp);
visited[temp]=true;
if(++In[temp]>n)return ;
} }
}
}
} void work ( int x )
{
int i,t,temp;
queue<int> Q;
memset(visited,,sizeof(visited));
memset(Dis,0x3f,sizeof(Dis));
memset(In,,sizeof(In));
int S = , haha ; haha = e[ x ].w , e[ x ].w = INF ;//删边
Q.push( S );
visited[ S ] = true;
Dis[ S ] = 0 ; while( !Q.empty ( ) )//SPFA
{
t=Q.front ( ) ;Q.pop ( ) ;visited[ t ] = false ;
for( i=p[t] ; i ; i = e[ i ].next )
{
temp = e[ i ].to;
if(Dis[ temp ] > Dis[ t ] + e[ i ].w )
{
Dis[ temp ] = Dis[ t ]+e[ i ].w ;
if( !visited[ temp ] )
{
Q.push ( temp ) ;
visited[ temp ] = true ;
if( ++In[ temp ] > n )return ;
}
}
}
}
e[ x ].w = haha ;//恢复
} int main()
{
int x , y , _ ; scanf ( "%d%d" , &n , &m ) ;
for(int i= ; i<=m ; ++i )
{
scanf ( "%d%d%d" , &x , &y , &_ ) ;
Add_edge( x , y , _ ) ;
Add_edge( y , x , _ ) ;
} Spfa( ) ;
int ans = Dis [ n ] ; for ( int i=n ; i!= ; i =e[ pre[ i ] ].from ){
work ( pre[ i ] ) ;
ans = max ( ans , Dis[ n ] ) ;//比较最大值
}
printf ( "%d" , ans ) ;
return ;
}

(完)

最新文章

  1. ubuntu无限卡在logo界面
  2. hibernate不同版本获取获取sessionFactory
  3. Time.MONTH及Calendar.MONTH 默认的月份为 0-11
  4. Windows的bat脚本中for循环
  5. NUI四种提交数据方式c
  6. 基于mini2440的boa服务器移植
  7. 网络IPC:套接字之非阻塞和异步I/O
  8. IE6与W3C标准的盒模型差异
  9. ThoughtWorks开发持续集成及部署利器:Go
  10. Compile Time Assertion..
  11. 基于Spring Cloud和Netflix OSS 构建微服务-Part 1
  12. Python之Mock的入门
  13. MySQL中select、insert、update批量操作语句
  14. P3399 丝绸之路 dp
  15. c# 在mongo中查询经纬度范围
  16. python实现最大重叠子串的查找
  17. js-ES6学习笔记-module(1)
  18. Facebook人工智能实验室的前世今生
  19. centos7 安装后需要做的事情
  20. Javascript-逻辑判断或(&amp;&amp;)练习

热门文章

  1. Linux USB Project
  2. java 泛型 -- 泛型类,泛型接口,泛型方法
  3. Delphi中线程类TThread实现多线程编程2---事件、临界区、Synchronize、WaitFor……
  4. 几年前做家教写的C教程(之二)
  5. 一个通过网络转换Ico到Png图片的小小程序(Ico2Png)
  6. SQL Server排序规则
  7. PHP实现上一篇、下一篇
  8. hdu 4741 2013杭州赛区网络赛 dfs ***
  9. 单链表带头结点&amp;不带头结点
  10. 自己制作QQ空间音乐的具体方法