您的位置:首页 > 其它

UVA - 1599(BFS求最优路)

2016-06-23 15:16 375 查看
New labyrinth attraction is open in New Lostland amusement park. The labyrinth consists of n rooms

connected by m passages. Each passage is colored into some color ci

. Visitors of the labyrinth are

dropped from the helicopter to the room number 1 and their goal is to get to the labyrinth exit located

in the room number n.

Labyrinth owners are planning to run a contest tomorrow. Several runners will be dropped to the

room number 1. They will run to the room number n writing down colors of passages as they run

through them. The contestant with the shortest sequence of colors is the winner of the contest. If there

are several contestants with the same sequence length, the one with the ideal path is the winner. The

path is the ideal path if its color sequence is the lexicographically smallest among shortest paths.

Andrew is preparing for the contest. He took a helicopter tour above New Lostland and made a

picture of the labyrinth. Your task is to help him find the ideal path from the room number 1 to the

room number n that would allow him to win the contest.

Note: A sequence (a1, a2, … , ak) is lexicographically smaller than a sequence (b1, b2, … , bk) if there

exists i such that ai < bi

, and aj = bj for all j < i.

Input

The input file contains several test cases, each of them as described below.

The first line of the input file contains integers n and m — the number of rooms and passages,

respectively (2 ≤ n ≤ 100000, 1 ≤ m ≤ 200000). The following m lines describe passages, each passage

is described with three integer numbers: ai

, bi

, and ci — the numbers of rooms it connects and its

color (1 ≤ ai

, bi ≤ n, 1 ≤ ci ≤ 109

). Each passage can be passed in either direction. Two rooms can be

connected with more than one passage, there can be a passage from a room to itself. It is guaranteed

that it is possible to reach the room number n from the room number 1.

Output

For each test case, the output must follow the description below.

The first line of the output file must contain k — the length of the shortest path from the room

number 1 to the room number n. The second line must contain k numbers — the colors of passages in

the order they must be passed in the ideal path.

Sample Input

4 6

1 2 1

1 3 2

3 4 3

2 3 1

2 4 4

3 1 1

Sample Output

2

1 3

题意:任性的labyrinth主人要举行一场比赛。所有人都被投掷到第一个房间,他们要找到去最后一个房间的最优路径。从一个房间到另一个房间的路上被涂上了颜色,颜色用数字表示,而且通道可能是自己到自己,绕了个圈。最优路径要求走过的通道数是最少的,如果走过的通道数一样,那就看走过通道的颜色,颜色路径字典序越小越好。

题解:先用BFS算出每个节点到终点的最短路径,这时候第一个房间到终点的最短路径就求出来了。每一层都比下一层到n的距离多1,用一次BFS求出一层到下一层的最小颜色编号,可是可能好多通道的颜色一样,所以这些通道的方案都要遍历,再用一次BFS求出所以下一层最小颜色编号的房间,存储进来,将这些最小颜色编号的房间都当作这一层的节点,一直搜索下去。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <map
4000
>
#include <queue>
#include <cmath>
#include <vector>

//过道结构体
struct edge{
int a, b, c;
edge(int a = 0, int b = 0, int c = 0): a(a), b(b), c(c) {}
};

using namespace std;

const int maxn = 100000 + 5;
const int INF = 1000000000 + 5;//INF一定要开的足够大
int n, m, d[maxn], vis[maxn];
vector<edge> edges;//储存过道
vector<int> g[maxn];//储存通经过每个房间的过道号
vector<int> ans;//储存最优路径的颜色编号

//将过道加入edges并储存g
void addedge(int a, int b, int c)
{
edges.push_back(edge(a, b, c));
int index = edges.size() - 1;//index为编号
g[a].push_back(index);//储存到a的过道编号中
}

//计算每个节点到终点的最短路径
void rev_BFS()
{
memset (vis, 0, sizeof(vis));
int now;
queue<int> q;
d[n - 1] = 0;
vis[n - 1] = 1;
q.push(n - 1);
while (!q.empty()) {
now = q.front(); q.pop();
for (int i = 0; i < g[now].size(); i++) {
int e = g[now][i];
int b = edges[e].b;
if (!vis[b]) {
vis[b] = 1;
d[b] = d[now] + 1;
q.push(b);
//cout << edges[e].c << endl;
}
}
}
/*for (int i = 0; i < n; i++) {
cout << d[i] << endl;
//cout << g[i].size() << endl;
}*/
}

//查找最优路径,也就是路径最短,颜色最小路径,并输出
void BFS()
{
int u, v;
memset (vis, 0, sizeof(vis));
vector<int> next;//储存本层同为最优路径的房间
next.push_back(0);
vis[0] = 1;
//这个大循环用于算每一步
for (int i = d[0]; i > 0; i--) {
int min_color = INF;//储存最优颜色
//这个循环用于BFS出每个节点到下一层的最优颜色
for (int l = 0; l < next.size(); l++) {
u = next[l];
for (int j = 0; j < g[u].size(); j++) {
v = edges[g[u][j]].b;
if (d[v] == d[u] - 1 && edges[g[u][j]].c < min_color) {
min_color = edges[g[u][j]].c;
}
}
}
ans.push_back(min_color);
//cout << min_color << endl;

//BFS出下一层
vector<int> next2;//储存所有下一层同为最优路径的房间
for (int l = 0; l < next.size(); l++) {
u = next[l];
for (int j = 0; j < g[u].size(); j++) {
int e = g[u][j];
v = edges[e].b;
if (d[v] == d[u] - 1 && edges[e].c == min_color && !vis[v]) {
next2.push_back(v);
vis[v] = 1;
}
}
}
next = next2;
}

printf("%d\n%d", d[0], ans[0]);
for(int i = 1; i < ans.size(); ++i) printf(" %d", ans[i]);
puts("");
}

int main()
{
#ifndef ONLINE_JUDGE
freopen ("in.txt", "r", stdin);
#endif // ONLINE_JUDGE
int a, b, c;
while (cin >> n >> m) {
edges.clear();
ans.clear();
for (int i = 0; i < n; i++) {
g[i].clear();
}
memset (d, -1, sizeof(d));
while (m--) {
cin >> a >> b >> c;
if (a == b) continue;
addedge (a - 1, b - 1, c);//由于习惯从0开始,所以全-1
addedge (b - 1, a - 1, c);//这是无向图,两相过道都要存储
}

rev_BFS ();
BFS();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: