2个dfs遍历,第一个用的优先队列~第二个直接BFS就行了
不要把这题想的太复杂了,尤其是第二个保存路径的,只要记录每次走到哪个位置就行了
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<stack>
#include<queue>
#include<map>
#include<vector>
using namespace std;
#define INF 1 << 30
#define MAXD 100000 + 10
#define MAX_SIZE 400000 + 10
typedef pair<int,int> pill;
int n,m;
int Right[MAX_SIZE];
int Color[MAX_SIZE];
int dist[MAXD]; /*其余点到终点的距离*/
int ans[MAXD];
vector<int>G[MAXD];
struct State{
int pos; /*当前位置*/
vector<int>arr; /*当前路径*/
};
void GetDistance_dfs(int u,int d){ /*寻找每个点到终点的最短距离*/
priority_queue<pill,vector<pill>,greater<pill> >q;
q.push(make_pair(0,n));
int vis[MAXD] = {0};
vis[n] = 1;
while(!q.empty()){
pill t = q.top(); q.pop();
int _dist = t.first;
int pos = t.second;
for(int i = 0 ; i < G[pos].size(); i++){
int l = G[pos][i];
int r = Right[l];
if(!vis[r]){
vis[r] = 1;
dist[r] = _dist + 1;
q.push(make_pair(_dist + 1,r));
}
}
}
return ;
}
void GetPrintf_dfs(){
queue<int>q;
q.push(1);
int vis[MAXD] = {0};
while(!q.empty()){
int pos = q.front();
q.pop();
int _MIN = INF;
for(int i = 0 ; i < G[pos].size(); i++){
int l = G[pos][i];
int r = Right[l];
int c = Color[l];
if(dist[pos] - 1 == dist[r] && c < _MIN){ /*先选出最短路径*/
_MIN = c;
}
}
int now_step = dist[1] - dist[pos];
if(ans[now_step] == -1)
ans[now_step] = _MIN;
else
ans[now_step] = min(ans[now_step],_MIN);
for(int i = 0 ; i < G[pos].size(); i++){
int l = G[pos][i];
int r = Right[l];
int c = Color[l];
if(!vis[r] && _MIN == c && dist[r] == dist[pos] - 1){
q.push(r);
vis[r] = 1;
/*这里不要忘了标记,去除重复,因为如果一个节点之前走到过,那么是不可能再走回来的!*/
}
}
}
}
int main(){
while(scanf("%d%d",&n,&m) != EOF){
for(int i = 1 ; i <= n ; i++) G[i].clear(); /*初始化*/
for(int i = 1 ; i <= n ; i++) dist[i] = INF;
dist[n] = 0;
for(int i = 1 ; i <= m ; i++){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
if(x != y){
G[x].push_back(i);
Right[i] = y;
Color[i] = z;
G[y].push_back(i + m);
Right[i + m] = x;
Color[i + m] = z;
}
}
GetDistance_dfs(n,0);
memset(ans,-1,sizeof(ans));
GetPrintf_dfs();
printf("%d\n",dist[1]);
for(int i = 0 ; i < dist[1]; i++){
printf("%d",ans[i]);
if(i < dist[1] - 1)
printf(" ");
}
printf("\n");
}
return 0;
}