您的位置:首页 > 其它

【算法竞赛入门经典】6.5[图的BFS] 例题6-20 UVa1599

2018-02-02 18:57 399 查看

【算法竞赛入门经典】6.5[图的BFS] 例题6-20 UVa1599

算法竞赛入门经典65图的BFS 例题6-20 UVa1599
例题UVa1599

思路

本题储存结构

样例实现代码

例题UVa1599

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

思路

去掉所谓的字典序,本题实际上就是普通的最短路径问题,可以用BFS解决。在无需记录父节点的情况下,可以逆序进行BFS,即从最后一个节点开始进行BFS,直到遍历所有节点,此时第一个节点的Dis值就是距离终点的最短值;走过的路径就是最短路径。用数组Dis记录下所有节点的数据。

此时便可以进行一遍正序的DFS,对每一个节点,求得Dis比它本身节点的值小1的那个节点,即为可能的的下一步,过程中记录下最小字典序。接着,再遍历一次本节点的下一个节点,对比距离和耗费都符合的节点,放入vector当中,即求了下一个可能节点。

这样,就能求得路径上的耗费序列。

本题储存结构

本题主要需要记录的是图的边的信息。【因为两个节点之间可能有多个直接路径,不能简单的记录节点之间的联系了】每一个边的信息用结构体adj记录。

typedef struct adj {
int u;
int v;
int c;
adj(int u,int v,int c):u(u),v(v),c(c){}
}adj;


方便起见,可以为这些边标号,借助

vector<adj>edges;


这样之后给每个点增加边的时候只需要加入一个标号就可以了

每个点的信息就用如下存储

vector<int>G[MAX];


样例实现代码

TIP:没在UVa上测试,仅通过本样例。

#include<iostream>
#include<queue>
#include<vector>
#define MAX 100000+5
using namespace std;
typedef struct adj { int u; int v; int c; adj(int u,int v,int c):u(u),v(v),c(c){} }adj;
vector<adj>edges;
vector<int>G[MAX];
int Dis[MAX];
bool visited[MAX];
int addedge(int u, int v, int c) {
edges.push_back(adj(u, v, c));
int n = edges.size() - 1;
G[u].push_back(n);
return n;
}
int n;
void refbfs() {
queue<int>point;
memset(Dis, 0, sizeof(Dis));
memset(visited, 0, sizeof(visited));
Dis[n - 1] = 0;
visited[n - 1] = true;
point.push(n - 1);
while (!point.empty()) {
int ts = point.front();
point.pop();
for (int i = 0; i < G[ts].size(); i++) {
int temp = edges[G[ts][i]].v;
if (!visited[temp]) {
visited[temp] = true;
Dis[temp] = Dis[ts] + 1;
point.push(temp);
}
}
}
}
void bfs() {
vector<int>ans;
vector<int>next;
vector<int>next2;
next.push_back(0);
memset(visited, 0, sizeof(visited));
for (int i = 0; i < Dis[0]; i++) {
next2.clear();
int minc = INT_MAX;
for (int j = 0; j < next.size(); j++) {
int u = next[j];
for (int k = 0; k < G[u].size(); k++) {
int v = edges[G[u][k]].v;
if (Dis[u] == Dis[v] + 1)
minc = min(minc, edges[G[u][k]].c);
}
}
ans.push_back(minc);
for (int j = 0; j < next.size(); j++) {
int u = next[j];
for (int k = 0; k < G[u].size(); k++) {
int v = edges[G[u][k]].v;
if (Dis[u] == Dis[v] + 1 && !visited[v] && edges[G[u][k]].c == minc) {
visited[v] = true;
next2.push_back(v);
}
}
}
next = next2;
}
cout << ans.size() << endl;
for (int i = 0; i < ans.size() - 1; i++)
cout << ans[i] << " ";
cout << ans[ans.size() - 1] << endl;
}
int main() {
int u, v, c, m;
while (cin >> n >> m) {
for (int i = 0; i < n; i++) {
G[i].clear();
}
edges.clear();
while (m--) {
cin >> u >> v >> c;
addedge(u-1, v-1, c);
addedge(v-1, u-1, c);
}
refbfs();
bfs();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: