思路和书上思路一样!
先 从终点BFS,用d数组记录到终点的最短距离,直接从0开始不断加1即可!
扫到起点后,在从起点开始BFS,走路的条件必须满足,下一个路 加 1 等于这个路,而且没有访问过 vis[i] = 0,然后在是字典序最小(把所有字典序最小的全部加入!)
最后存入答案时,用step 记录从1走到当前步的步数,这个数值就是答案的 索引,最后答案存入所有路中最小字典序就行了!
这里连接整个图时,最好用vector 数组,room[a][i],表示a与i相连!颜色也是如此。
注意一个细节:
INF 也就是最大颜色值是10^9不要开的太小!
#include<bits/stdc++.h>
using namespace std;
const int maxn = 100000 + 10;
vector<int>room[maxn];
vector<int>color[maxn];
const int INF = 1e9+10;
int ans[maxn];
int d[maxn];
int vis[maxn];
int n,m;
void BFS1(){
queue<int>q;
q.push(n);
d[n]=0;
while(!q.empty()){
int u = q.front();q.pop();
if (u == 1)return;
int len = room[u].size();
for (int i = 0; i < len; ++i){
int v = room[u][i];
if (d[v] < 0){
d[v] = d[u] + 1;
q.push(v);
}
}
}
}
void BFS2(){
queue<int>q;
q.push(1);
while(!q.empty()){
int u = q.front();q.pop();
if(u == n)return;
int len = room[u].size();
int t = INF;
for (int i = 0; i < len; ++i){
int v = room[u][i];
if (d[v] == d[u] - 1)t = min(t,color[u][i]);
}
int step = d[1] - d[u];
if (!ans[step])ans[step] = t;
else ans[step] = min(t,ans[step]);
for (int i = 0; i < len; ++i){
int v = room[u][i];
if (vis[v] == 0 && t == color[u][i] && d[v] == d[u] - 1){
vis[v] = 1;
q.push(v);
}
}
}
}
int main()
{
while(scanf("%d%d",&n,&m) == 2){
memset(vis,0,sizeof(vis));
memset(d,-1,sizeof(d));
memset(ans,0,sizeof(ans));
for (int i = 0; i < maxn; ++i){
room[i].clear();
color[i].clear();
}
while(m--){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if (a == b)continue;
room[a].push_back(b);
room[b].push_back(a);
color[a].push_back(c);
color[b].push_back(c);
}
BFS1();
BFS2();
printf("%d\n%d",d[1],ans[0]);
for (int i = 1; i < d[1]; ++i)printf(" %d",ans[i]);
printf("\n");
}
return 0;
}