Description

 
Student Ilya often skips his classes at the university. His friends criticize him for this, but they don’t know that Ilya spends this time not watching TV serials or listening to music. He creates a computer game of his dreams. The game’s world is a forest. There are elves, wooden houses, and a villain. And one can rob caravans there! Though there is only one caravan in the game so far, Ilya has hard time trying to implement the process of robbing.
The game world can be represented as several settlements connected by roads. It is possible to get from any settlement to any other by roads (possibly, passing through other settlements on the way). The settlements are numbered by integers from 1 to  n. All the roads are two-way and have the same length equal to 1. It is not allowed to move outside the roads. The caravan goes from settlement  s to settlement  f following one of the shortest routes. Settlement  r is the villain’s den. A band of robbers from settlement  r has received an assignment to rob the caravan. In the evening they will have an exact plan of the route that the caravan will take the next morning. During the night they will be able to move to any settlement on the route, even to settlement  s or  f. They will lay an ambush there and rob the caravan in the morning. Of course, among all such settlements the robbers will choose the one closest to settlement  r. The robbers have a lot of time until the evening. They don’t know the caravan’s route yet, but they want to know the maximum distance they will have to go in the worst case to the settlement where they will rob the caravan. Help Ilya calculate this distance, and it may happen that he will attend his classes again!

Input

The first line contains integers n and m (3 ≤ n ≤ 10 5; 2 ≤ m ≤ 10 5), which are the number of settlements in the game world and the number of roads between them. Each of the following m lines describes a road. The description contains integers a and  b, which are the numbers of the settlements connected by the road. It is guaranteed that each road connects two different settlements and there is at most one road between any two settlements. It is also guaranteed that the road network is connected. In the last line you are given pairwise different integers sf, and r, which are the numbers of the settlements described above.

Output

In the only line output the required distance.
 
input output
7 7
1 2
2 4
2 5
3 4
4 6
5 6
6 7
1 7 3
2
 
 
 
题目大意:
大意是有一支商队要从点 s 到点 f,这个商队只会走走短路(题目保证能从 s 到 f ,同时,走每条边的时间花费都是 1),有一个强盗在点 r ,这个强盗要去抢商队
就问你在最坏情况下,强盗能够拦截到这个商队所需走的最短距离.
比如样例:
这里商队需要从点 1 到点 7 ,强盗在点 3,我们可以很容易知道商队的路线有两条:
1 -> 2 -> 4 ->6 -> 7
1 -> 2 -> 5 ->6 -> 7
而在最坏情况下,也就是商队走1->2->5->6->7时,强盗在点 3 想要拦截到商队需要至少走两步(到 2 或者 6 ) 才能拦截到商队
所以样例的输出是 2
 
 
解题报告:
首先我们肯定需要求一次最短路,这个最短路是强盗所在的点 r ,到其他各个点的最短路,我们不妨设置值为 maxv[](不要奇怪这个命名)
即maxv[ x ]表示点 r 到点 x 的最短距离.
显然我们这道题需要使用到DP(递推)求解,注意到这些递推的点必须是最短路上的点同时也必须只能转移到最短路上的点,那么我们该如何确定这个最短路的点呢?
我们令 d[] 这个数组表示从终点 f 到其他各个点的最短距离,那么我们只要在转移时必须满足 d[v] == d[u] - 1 即可(从u转移到v) <仔细想想>
这样我们就保证了递推过程的点肯定是最短路上的点,也只能转移到最短路上的点
之后我们考虑DP值,我们令DP[ i ] 表示拦截从 起点 到 i 这个点所在的最短路的最小花费
那么我们很容易的就可以得出递推方程(用 u 去更新 v)
dp[v] = max( maxv[u] } <仔细想想> ,取max是因为我们要保证最差情况
 
那么当我们扩展到点 u时,需要首先更新 maxv 值,即 maxv[u] = min{ maxv[u] , dp[u] } ,这个方程就非常容易了,因为拦截从 起点 到 点i所在的最短路不外乎就两种方式,一种在前面拦截,第二种在这个点 i 拦截,所以我们取个min即可(强盗也要走最短的对不对)
 
那么,我们就解决了这道题
 
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
const int maxn = 1e5 + ;
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
vector<int>e[maxn];
int dp[maxn] , d[maxn] , maxv[maxn], n , m , s , f , r , used[maxn] ;
queue<int>q; void solve()
{
memset(dp , , sizeof(dp));memset(d,-,sizeof(d));memset(maxv,-,sizeof(maxv));memset(used,,sizeof(used));
d[f] = ;
q.push(f);
while(!q.empty())
{
int x = q.front();q.pop();
for(int i = ; i < e[x].size() ; ++ i)
{
int v = e[x][i];
if (d[v] == -)
{
d[v] = d[x] + ;
q.push(v);
}
}
}
maxv[r] = ;
q.push(r);
while(!q.empty())
{
int x = q.front();q.pop();
for(int i = ; i < e[x].size() ; ++ i)
{
int v = e[x][i];
if (maxv[v] == -)
{
maxv[v] = maxv[x] + ;
q.push(v);
}
}
}
dp[s] = maxv[s];used[s] = ;
q.push(s);
while(!q.empty())
{
int x = q.front();q.pop();
maxv[x] = min(maxv[x],dp[x]);
for(int i = ; i < e[x].size() ; ++ i)
{
int v = e[x][i];
if (d[x] - d[v] == )
{
dp[v] = max(dp[v],maxv[x]);
if (!used[v])
{
q.push(v);
used[v] = ;
}
}
}
}
printf("%d\n",maxv[f]);
} int main(int argc,char *argv[])
{
scanf("%d%d",&n,&m);
while(m--)
{
int u ,v ;
scanf("%d%d",&u,&v);u--,v--;
e[u].push_back(v);e[v].push_back(u);
}
scanf("%d%d%d",&s,&f,&r);s--,f--,r--;
solve();
return ;
}
 

URAL 2034 : Caravans的更多相关文章

  1. URAL 2034 Caravans(变态最短路)

    Caravans Time limit: 1.0 secondMemory limit: 64 MB Student Ilya often skips his classes at the unive ...

  2. URAL

    URAL 2035 输入x,y,c,  找到任意一对a,b 使得a+b==c&& 0<=a<=x && 0<=b<=y 注意后两个条件,顺序搞错 ...

  3. hdu 2034人见人爱A-B

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2034 解题思路:set的基本用法 #include<iostream> #include& ...

  4. 后缀数组 POJ 3974 Palindrome && URAL 1297 Palindrome

    题目链接 题意:求给定的字符串的最长回文子串 分析:做法是构造一个新的字符串是原字符串+反转后的原字符串(这样方便求两边回文的后缀的最长前缀),即newS = S + '$' + revS,枚举回文串 ...

  5. ural 2071. Juice Cocktails

    2071. Juice Cocktails Time limit: 1.0 secondMemory limit: 64 MB Once n Denchiks come to the bar and ...

  6. ural 2073. Log Files

    2073. Log Files Time limit: 1.0 secondMemory limit: 64 MB Nikolay has decided to become the best pro ...

  7. ural 2070. Interesting Numbers

    2070. Interesting Numbers Time limit: 2.0 secondMemory limit: 64 MB Nikolay and Asya investigate int ...

  8. ural 2069. Hard Rock

    2069. Hard Rock Time limit: 1.0 secondMemory limit: 64 MB Ilya is a frontman of the most famous rock ...

  9. ural 2068. Game of Nuts

    2068. Game of Nuts Time limit: 1.0 secondMemory limit: 64 MB The war for Westeros is still in proces ...

随机推荐

  1. COM编程入门第二部分——深入COM服务器

    本文为刚刚接触COM的程序员提供编程指南,解释COM服务器内幕以及如何用C++编写自己的接口.继上一篇COM编程入门之后,本文将讨论有关 COM服务器的内容,解释编写自己的COM接口和COM服务器所需 ...

  2. 窥探 Swift 之 函数与闭包的应用实例

    今天的博客算是比较基础的,还是那句话,基础这东西在什么时候 都是最重要的.说到函数,只要是写过程序就肯定知道函数是怎么回事,今天就来讨论一下Swift中的函数的特性以及Swift中的闭包.今天的一些小 ...

  3. 【C++深入探索】Copy-and-swap idiom详解和实现安全自我赋值

    分类: C/C++2012-08-30 21:40 2017人阅读 评论(2) 收藏 举报 任何管理某资源的类比如智能指针需要遵循一个规则(The Rule of Three): 如果你需要显式地声明 ...

  4. LSI MegaCli 命令使用4

    Dell服务器常用管理命令总结准备新版本的 MegaCli-1.01.24-0.i386.rpm 会把程序安装在/opt下,可以自定义安装目录,例如:rpm --relocate /opt/=/usr ...

  5. h5 canvas

    概述 Canvas API(画布)用于在网页实时生成图像,并且可以操作图像内容,基本上它是一个可以用JavaScript操作的位图(bitmap). 使用前,首先需要新建一个canvas网页元素. & ...

  6. 嵌套repeater

    通过外层repeater的值来进行内层repeater的数据绑定 前台代码部分: <asp:repeater runat="server" id="repeater ...

  7. SqlServer数据库设计,纠结的问题,有胆你就来!

    最近,小菜遇到了数据库设计上的一个问题,希望各位大侠再次,直抒己见,帮忙分析一下.也可有更好的设计,请直接提出来. 要求:数据库(SQL Server 2005)存储每个学生,单个客观题答案.分数,主 ...

  8. Python----定义

    变量的定义: 变量第一次出现不是声明类型就是赋初值,才能后续使用. 函数的定义: ''' 函数的返回值不用声明类型 函数参数值最好赋一个类型值,例如整型赋值0,列表[] 函数名后面必须跟: ''' d ...

  9. class类名的管理

    var a=document.querySelector(".div1"); a.classList.remove("div2");//减掉一个 a.class ...

  10. DBA优化SQL采用的WITH AS 用法简介

    一.WITH AS简介 WITH AS的用法从oracle 9i新增的,官方文档也称之为:subquery factoring;在进行复杂的查询.统计等操作时使用with as 子句可以大大提高性能! ...