思路:第一遍bfs从终点开始,找到每个点到终点的最短距离。第二遍bfs先找到最小的颜色值,然后将每个颜色值最小的点入队
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
const int N = 102400;
const int INF = 0x3f3f3f3f;
vector<int> v[N],col[N]; //col存颜色,开数组开不了
int d[N],vis[N],ans[N]; //d数组代表每个点到终点的距离
int n,m;
void bfs1()
{
memset(d,-1,sizeof d);
queue <int> q;
q.push(n);
d[n] = 0;
while(!q.empty()){
int a = q.front();
q.pop();
for(int i = 0 ; i < v[a].size();i++){
int e = v[a][i];
if(d[e] == -1){
d[e] = d[a]+1;
if(e == 1) return;
q.push(e);
}
}
}
}
void bfs2()
{
memset(vis,0,sizeof vis);
queue<int> q;
q.push(1);
memset(ans,0,sizeof ans);
while(!q.empty()){
int h = q.front();
q.pop();
if(h == n) break;
int t = INF; //t的初值用2*N 不行
for(int i = 0 ; i < v[h].size();i++){
int e = v[h][i];
if(col[h][i] < t && d[h] == d[e]+1) t = col[h][i];
}
if(!ans[d[h]] || t < ans[d[h]]) ans[d[h]] = t;
else continue;
for(int i = 0 ; i < v[h].size();i++){
int e = v[h][i];
if(d[h] == d[e]+1 && col[h][i] == t && !vis[e]){
q.push(e);
vis[e] = 1;
}
}
}
printf("%d\n%d",d[1],ans[d[1]]);
for(int i = d[1] - 1 ; i > 0; i--){
printf(" %d",ans[i]);
}
printf("\n");
}
int main()
{
while(cin >> n >> m){
for(int i = 0 ; i <= n ;i++){
v[i].clear();
col[i].clear();
}
for(int i = 0 ; i < m ; i++){
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
v[a].push_back(b);col[a].push_back(c);
v[b].push_back(a);col[b].push_back(c);
}
bfs1();//求每个节点到终点的节点数
bfs2();
}
return 0;
}