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求出所以下一层最小颜色编号的房间,存储进来,将这些最小颜色编号的房间都当作这一层的节点,一直搜索下去。
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; }
相关文章推荐
- iOS开发经验总结1
- PID控制理論(2)-P control
- RemoteViews的应用
- Java源码-任意字符的Unicode查询
- Android studio 开发者信息设置
- jQuery全选/反选checkbox
- 已经迁移到简书写作了
- SVN打基线
- 二叉树的递归实现(先,中,后)
- BZOJ3060: [Poi2012]Tour de Byteotia
- 使用UITextFiled收回键盘的几种方法
- Linux上安装Python的PIL和Pillow库处理图片的实例教程
- JavaEE_SAX
- jQuery练习一好友列表变色
- Python-S13作业-day1-之登陆程序
- 第13周 关于二叉树的遍历方法
- In Gradle projects, always use http://schemas.android.com/apk/res-auto for custom attributes
- android TextView 垂直自动滚动
- Android中正确保存view的状态
- CSS Secret——CSS的浏览器兼容