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 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.

思路:次短路模板  注意要判断该图中是否有最短路

#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;

#define LOOP(i, n) for (int i = 1; i <= n; ++i)
const int MAX_NODE = 50005;
const int MAX_EDGE = 100005 << 1;
const int INF = 0x3f3f3f3f;

struct Node;
struct Edge;

struct Node {
    int Id, Dist, Dist2;
    bool Inq;
    Edge *Head;
} _nodes[MAX_NODE], *Start, *Target;
int _vCount;

struct Edge {
    int Weight;
    Node *From, *To;
    Edge *Next;
    Edge() {}
    Edge(Node *from, Node *to, Edge *next, int weight) :
        From(from), To(to), Next(next), Weight(weight) {}
} *_edges[MAX_EDGE];
int _eCount;

void Init(int vCount) {
    memset(_nodes, 0, sizeof _nodes);
    _vCount = vCount;
    _eCount = 0;
    Start = 1 + _nodes;
    Target = vCount + _nodes;
}

void AddEdge(Node *from, Node *to, int weight) {
    Edge *e = _edges[++_eCount] = new Edge(from, to, from->Head, weight);
    e->From->Head = e;
}

void Build(int uId, int vId, int weight) {
    Node *u = uId + _nodes, *v = vId + _nodes;
    u->Id = uId;
    v->Id = vId;
    AddEdge(u, v, weight);
}

void SPFA() {
    LOOP(i, _vCount)
    _nodes[i].Dist = _nodes[i].Dist2 = INF;
    static queue<Node*> q;
    Start->Dist = 0;
    Start->Dist2 = INF;
    Start->Inq = true;
    q.push(Start);
    while (!q.empty()) {
        Node *u = q.front();
        q.pop();
        u->Inq = false;
        for (Edge *e = u->Head; e; e = e->Next) {
            bool relaxOk = false;
            if (u->Dist + e->Weight < e->To->Dist) {
                e->To->Dist2 = e->To->Dist;
                e->To->Dist = u->Dist + e->Weight;
                relaxOk = true;
            }
            else if (u->Dist + e->Weight > e->To->Dist && u->Dist + e->Weight < e->To->Dist2) {
                e->To->Dist2 = u->Dist + e->Weight;
                relaxOk = true;
            }
            if (u->Dist2 + e->Weight < e->To->Dist2) {
                e->To->Dist2 = u->Dist2 + e->Weight;
                relaxOk = true;
            }
            if (relaxOk && !e->To->Inq) {
                e->To->Inq = true;
                q.push(e->To);
            }
        }
    }
}

int main() {
    int totNode, totEdge;
    int uId, vId, weight;
    scanf("%d%d", &totNode, &totEdge);
    Init(totNode);
    LOOP(i, totEdge) {
        scanf("%d%d%d", &uId, &vId, &weight);
        Build(uId, vId, weight);
    }
    SPFA();
    if (Target->Dist2 == INF) printf("-1\n");
    else printf("%d\n", Target->Dist2);
    return 0;
}

原文地址:https://www.cnblogs.com/v-vip/p/9808302.html

时间: 2024-08-05 08:19:32

codevs 1269 匈牙利游戏的相关文章

求次短路 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 fo

【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

codevs 1229 数字游戏

1229 数字游戏 http://codevs.cn/problem/1229/ 题目描述 Description Lele 最近上课的时候都很无聊,所以他发明了一个数字游戏来打发时间.  这个游戏是这样的,首先,他拿出几张纸片,分别写上0到9之间的任意数字(可重复写某个数字),然后,他叫同学随便写两个数字X和K.Lele要做的事情就是重新拼这些纸牌,组成数字 T ,并且 T + X 是 K 的正整数倍. 有时候,当纸片很多的时候,Lele经常不能在一节课之内拼出来,但是他又想知道答案,所以,他

codevs 2853 方格游戏--棋盘dp

方格游戏:http://codevs.cn/problem/2853/ 这和传纸条和noip方格取数这两个题有一定的相似性,当第一眼看到的时候我们就会想到设计$dp[i][j][k][l]$(i,j表示一个人走到 i 行 j 个点,而另一个人走到 k 行第l个点)这么一个状态. 转移方程当然是$dp[i][j][k][l] = max{ dp[i-1][j][k-1][l] ,dp[i-1][j][k][l-1] ,dp[i][j-1][k-1][l] ,dp[i][j-1][k][l-1 }$

codevs 1198 国王游戏

传送门 题目描述 Description 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 n位大臣排成一排,国王站在队伍的最前面.排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果. 国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,使得获得奖赏最多的大臣

codevs——2853 方格游戏(棋盘DP)

时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description 菜菜看到了一个游戏,叫做方格游戏~ 游戏规则是这样的: 在一个n*n的格子中,在每个1*1的格子里都能获得一定数量的积分奖励,记左上角为(1,1),右下角为(n,n).游戏者需要选择一条(1,1)到(n,n)的路径,并获得路径上奖励的积分.对于路径当然也有要求啦,要求是只能往坐标变大的方向走[从(x,y)到(x+1,y)或者(x,y+1)],走过2n-1个区域到达(n,

codevs 2946 翻转游戏

2946 翻转游戏 题目描述 Description 现有n个数字a1,a2...an,其值均为0或1. 要求对着n个数中连续的若干个数进行一次取反(0->1,1->0),求所能得到的最多的1的数目. 输入描述 Input Description 第一行,n 第二行,n个数 输出描述 Output Description 能得到的最多的1的数目 样例输入 Sample Input 41 0 0 1 样例输出 Sample Output 4 数据范围及提示 Data Size & Hin

codevs 1153 道路游戏

传送门 题目描述 Description 小新正在玩一个简单的电脑游戏.游戏中有一条环形马路,马路上有n 个机器人工厂,两个相邻机器人工厂之间由一小段马路连接.小新以某个机器人工厂为起点,按顺时针顺序依次将这n 个机器人工厂编号为1~n,因为马路是环形的,所以第n 个机器人工厂和第1 个机器人工厂是由一段马路连接在一起的.小新将连接机器人工厂的这n 段马路也编号为1~n,并规定第i 段马路连接第i 个机器人工厂和第i+1 个机器人工厂(1 ≤ i ≤ n-1),第n 段马路连接第n 个机器人工厂