给一个n个点m条边(2≤n≤100000,1≤m≤200000)的无向图,每条边上都涂有一种颜色。求从结点1到结点n的一条路径,使得经过的边数尽量少,在此前提下,经过边的颜色序列的字典序最小。一对结点间可能有多条边,一条边可能连接两个相同结点。输入保证结点1可以达到结点n。颜色为1~109的整数。
tip:
一对结点间可能有多条边,一条边可能连接两个相同结点
一开始处理,不要环,选取两个结点之间最近的点
解题方法:
// 错误 for (int i = 0; i < next.size(); i++) { for (int j = 0; j < edge[i].size(); j++) { // 正确 for (int i = 0; i < next.size(); i++) { int thisedge = next[i]; for (int j = 0; j < edge[thisedge].size(); j++) {
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <vector> #include <queue> #include <string.h> //#define LOCAL using namespace std; const int maxn = 100000+5; const int INF = 1e9; struct Edge { int u; int v; int c; Edge(int a,int b,int d):u(a),v(b),c(d){} }; vector<Edge> edge[maxn]; int d[maxn]; int used[maxn]; int n, m; void rebfs() { memset(d, -1, sizeof(d)); memset(used, 0, sizeof(used)); queue<int> que; que.push(n); used[n] = 1; d[n] = 0; while (que.size()) { int nownode = que.front(); que.pop(); for (int i = 0; i < edge[nownode].size(); i++) { int nexnode = edge[nownode][i].v; if (!used[nexnode]) { d[nexnode] = d[nownode] + 1; used[nexnode] = 1; que.push(nexnode); } } } } vector<int> answer; void bfs() { memset(used, 0, sizeof(used)); answer.clear(); vector<int> next; used[1] = 1; next.push_back(1); int path = d[1]; while (path--) { int min = INF; for (int i = 0; i < next.size(); i++) { int thisedge = next[i]; for (int j = 0; j < edge[thisedge].size(); j++) { int theedge = edge[thisedge][j].v; if (d[theedge] == d[thisedge] - 1 && edge[thisedge][j].c < min) min = edge[thisedge][j].c; } } answer.push_back(min); vector<int> next2; for (int i = 0; i < next.size(); i++) { int thisedge = next[i]; for (int j = 0; j < edge[thisedge].size(); j++) { int theedge = edge[thisedge][j].v; if (d[theedge] == d[thisedge] - 1 && edge[thisedge][j].c == min && !used[theedge]) { next2.push_back(theedge); used[theedge] = 1; } } } next = next2; } } int main() { #ifdef LOCAL freopen("output.txt", "w", stdout); #endif // LOCAL while (scanf("%d%d", &n, &m) == 2) { for (int i = 0; i <= n; i++) { edge[i].clear(); } int a = m; while (a--) { int u, v, c; cin >> u >> v >> c; if (u != v) { Edge e = Edge(u, v, c); edge[u].push_back(e); e = Edge(v, u, c); edge[v].push_back(e); } } rebfs(); bfs(); printf("%d\n", d[1]); for (int i = 0; i < answer.size(); i++) { if (i == 0) printf("%d", answer[i]); else printf(" %d", answer[i]); } printf("\n"); } return 0; }