求次短路 codevs 1269 匈牙利游戏

codevs 1269 匈牙利游戏

2012年CCC加拿大高中生信息学奥赛

时间限制: 1 s

空间限制: 128000 KB

题目等级 : 钻石 Diamond

题目描述 Description

Welcome to the Hungary Games! The streets of Budapest form a twisted network of one-way streets.

欢迎来到匈牙利游戏!布达佩斯(匈牙利首都)的街道形成了一个弯曲的单向网络。

You have been forced to join a race as part of a “Reality TV” show where you race through these streets, starting at the Sz´echenyi thermal bath (s for short) and ending at the Tomb of G¨ ul Baba (t for short).

你被强制要求参加一个赛跑作为一个TV秀的一部分节目,比赛中你需要穿越这些街道,从s开始,到t结束。

Naturally, you want to complete the race as quickly as possible, because you will get more promo- tional contracts the better you perform.

很自然的,你想要尽快的完成比赛,因为你的比赛完成的越好,你就能得到更多的商业促销合同。

However, there is a catch: any person who is smart enough to take a shortest s-t route will be thrown into the P´alv¨olgyi cave system and kept as a national treasure. You would like to avoid this fate, but still be as fast as possible. Write a program that computes a strictly-second-shortest s-t route.

但是,有一个需要了解的是,如果有人过于聪明找到从s到t的最短路线,那么他就被扔到国家极品人类保护系统中作为一个国家宝藏收藏起来。你显然要避免这种事情的发生,但是也想越快越好。写一个程序来计算一个从s到t的严格次短路线吧。

Sometimes the strictly-second-shortest route visits some nodes more than once; see Sample Input 2 for an example.

有的时候,严格次短路线可能访问某些节点不止一次。样例2是一个例子。

输入描述 Input Description

The ?rst line will have the format N M, where N is the number of nodes in Budapest and M is the number of edges. The nodes are 1,2,...,N; node 1 represents s; node N represents t. Then there are M lines of the form A B L, indicating a one-way street from A to B of length L. You can assume that A != B on these lines, and that the ordered pairs (A,B) are distinct.

第一行包含两个整数N和M,N代表布达佩斯的节点个数,M代表边的个数。节点编号从1到N。1代表出发点s,N代表终点t。接下来的M行每行三个整数A B L,代表有一条从A到B的长度为L的单向同路。你可以认为A不等于B,也不会有重复的(A,B)对。

输出描述 Output Description

Output the length of a strictly-second-shortest route from s to t. If there are less than two possible lengths for routes from s to t, output −1.

输出从s到t的严格次短路的长度。如果从s到t的路少于2条,输出-1。

样例输入 Sample Input

样例输入1:

4 6

1 2 5

1 3 5

2 3 1

2 4 5

3 4 5

1 4 13

样例输入2:

2 2

1 2 1

2 1 1

样例输出 Sample Output

样例输出1:

11

样例输出2:

3

数据范围及提示 Data Size & Hint

对于样例1:

There are two shortest routes of length 10 (1 → 2 → 4,1 → 3 → 4) and the strictly-second- shortest route is 1 → 2 → 3 → 4 with length 11.

对于样例2:

The shortest route is 1 → 2 of length 1, and the strictly-second route is 1 → 2 → 1 → 2 of length 3.

 1 /*直接利用SPFA维护一个点到另一个点的最短路和次短路,维护方法如下:
 2 1、如果from的最短路能更新to的最短路,就让更新之前的最短路等于次短路,然后去更新最短路。
 3 2、如果from的最短路不能跟新to的最短路,但是可以更新次短路,就去更新次短路。
 4 3、如果form的最短路不能跟新to的最短路,也不能更新次短路,但是from的次短路可以更新to的次短路,那么就去更新次短路。
 5
 6 */
 7 #include<algorithm>
 8 #include<queue>
 9 #include<iostream>
10 using namespace std;
11 #include<cstdio>
12 #define N 50010
13 #define inf (1<<30)-1
14 bool inque[N]={0};
15 int n,m,a,b,l;
16 long long dis[N],cdis[N];
17 int head[N];
18 struct Edge{
19     int v,w,last;
20 }edge[1000000];
21 int t=0;
22 void add_edge(int u,int v,int w)
23 {
24     ++t;
25     edge[t].v=v;
26     edge[t].w=w;
27     edge[t].last=head[u];
28     head[u]=t;
29 }
30 void input()
31 {
32     cin>>n>>m;
33     //scanf("%d%d",&n,&m);
34     for(int i=1;i<=m;++i)
35     {
36         cin>>a>>b>>l;
37         //scanf("%d%d%d",&a,&b,&l);
38         add_edge(a,b,l);
39     }
40     for(int i=1;i<=n;++i)
41       dis[i]=cdis[i]=inf;
42 }
43 void spfa(int k)
44 {
45     queue<int>Q;
46     Q.push(k);
47     inque[k]=true;
48     dis[k]=0;//
49     while(!Q.empty())
50     {
51         int x=Q.front();
52         Q.pop();
53         inque[x]=false;
54         for(int l=head[x];l;l=edge[l].last)
55         {
56             if(dis[x]+edge[l].w<dis[edge[l].v])
57             {
58                 cdis[edge[l].v]=dis[edge[l].v];
59                 dis[edge[l].v]=dis[x]+edge[l].w;
60                 if(!inque[edge[l].v])
61                 {
62                     inque[edge[l].v]=true;
63                     Q.push(edge[l].v);
64                 }
65             }
66             else if(edge[l].w+dis[x]>dis[edge[l].v]&&dis[x]+edge[l].w<cdis[edge[l].v])//
67                  {
68                      cdis[edge[l].v]=dis[x]+edge[l].w;
69                      if(!inque[edge[l].v])
70                     {
71                     inque[edge[l].v]=true;
72                     Q.push(edge[l].v);
73                     }
74                  }
75             else if(cdis[edge[l].v]>cdis[x]+edge[l].w)//
76             {
77                 cdis[edge[l].v]=cdis[x]+edge[l].w;
78                 if(!inque[edge[l].v])
79                     {
80                     inque[edge[l].v]=true;
81                     Q.push(edge[l].v);
82                     }
83             }
84         }
85     }
86 }
87 int main()
88 {
89     input();
90     spfa(1);
91     if(cdis[n]==inf) cout<<-1;
92     else cout<<cdis[n]<<endl;
93     return 0;
94 }
时间: 2024-10-09 00:54:52

求次短路 codevs 1269 匈牙利游戏的相关文章

codevs 1269 匈牙利游戏

codevs 1269 匈牙利游戏 题目描述 Description Welcome to the Hungary Games! The streets of Budapest form a twisted network of one-way streets. 欢迎来到匈牙利游戏!布达佩斯(匈牙利首都)的街道形成了一个弯曲的单向网络. You have been forced to join a race as part of a "Reality TV" show where yo

【wikioi】1269 匈牙利游戏(次短路+spfa)

噗,想不到.. 次短路就是在松弛的时候做下手脚. 设d1为最短路,d2为次短路 有 d1[v]>d1[u]+w(u, v) 显然要更新d1,而因为d1是最短路,所以显然要先更新d2等于原来的d1再更新d1 d2[v]>d1[u]+w(u, v) && d1[v]>d1[u]+w(u, v) 因为现在 d1[u]+w(u, v) 不是最短路,但是又比次短路小,那么显然要更新次短路 d2[v]>d2[u]+w(u, v) 这时次短路比次短路短,那么肯定要更新次短路 #i

codevs 1512 转向游戏 题解

Codevs 1512转向游戏 题解 时间限制: 1 s 空间限制: 1000 KB 题目等级 : 白银 Silver 题解 题目描述 Description 小明自认为方向感很好,请小红来测试.小红先让小明面对北方立正站好,然后发出"向左转""向右转"或"向后转"的命令.每个命令执行后,小明都正确地说出了他面对的方向.小红的命令共N个(1≤n≤10000),请你统计小明说[南]的次数. 命令是以数字方式表达: 0---向左转 1---向右转 2

hdu1869六度分离,spfa实现求最短路

就是给一个图,如果任意两点之间的距离都不超过7则输出Yes,否则 输出No. 由于之前没写过spfa,无聊的试了一下. 大概说下我对spfa实现的理解. 由于它是bellmanford的优化, 所以之前会bf的理解起来,可能会比较容易. 它是这样子的,你弄一个队列, 先打一个起点进去,之后求出的到各点的最短路, 都是由这个点出发的. 然后开始迭代,直至队列为空, 在迭代的过程中, 首先从队列里面拿一个点出来, 然后标记一下,说明这个点不在队列里面, 然后开始枚举所有点,进行松弛化, 松弛化的过程

UVa 816 (BFS求最短路)

/*816 - Abbott's Revenge ---代码完全参考刘汝佳算法入门经典 ---strchr() 用来查找某字符在字符串中首次出现的位置,其原型为:char * strchr (const char *str, int c) ---BFS求最短路 --*/ #define _CRT_SECURE_NO_DEPRECATE #include<iostream> #include<string.h> #include<queue> #include<al

BZOJ_1001_狼抓兔子(平面图求最小割+对偶图求最短路)

描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1001 分析 平面图求最小割,转化成对偶图求最短路,经典. 注意: 1.优先队列是个大根堆. 2.Dijkstra可以带一个vis数组,也可以不带,因为一个点出来以后,它更新的的点和原本就在队列里的点都比它大,所以它不可能被更新得更小,之后这个点再出队时情况不比第一次更优,所以出队也不会有操作. 3.双向边,数组要开够(貌似不是第一次犯这个错误). 4.网上有人说m==1||n==1的情况可以

POJ 2251 Dungeon Master --- 三维BFS(用BFS求最短路)

POJ 2251 题目大意: 给出一三维空间的地牢,要求求出由字符'S'到字符'E'的最短路径,移动方向可以是上,下,左,右,前,后,六个方向,每移动一次就耗费一分钟,要求输出最快的走出时间.不同L层的地图,相同RC坐标处是相连通的.(.可走,#为墙) 解题思路:从起点开始分别往6个方向进行BFS(即入队),并记录步数,直至队为空.若一直找不到,则困住. /* POJ 2251 Dungeon Master --- 三维BFS(用BFS求最短路) */ #include <cstdio> #i

eoj1818 dijkstra求最短路及其条数

求出有n(1 < n <= 100)个结点有向图中,结点1到结点n的最短路径,以及最短路径的条数. Input 第一行有2个整数n和m( 0 < m < 3000),接下来m行每行有三个整数u,v,w结点u到v之间有一条权为w的边(w<100000). Output 输出只有一行,为结点1到结点n之间的最短路径及其条数(用空格隔开),如果1到n之间不存在路径,输出 -1 0. Sample Input 3 3 1 2 10 2 3 15 1 3 25 Sample Outpu

poj 3463 Sightseeing (dij 求最短路和次短路并计数)

dijkstra求最短路和次短路的求法和计算  模板 dijkstra求最短路的变形. 外循环要循环2*n-1次,因为dis[n][2]有2*n个状态,而dis[s][0]已经用过一次. 算法: 1.如果比最短路短就更新最短路和次短路. 2.如果和最短路相等,更新最短路的计数. 3.如果和次短路相等,更新次短路的方法数. 4.如果比次短路短,更新次短路. #include<cstdio> #include<iostream> #include<cstring> #inc