1599 - Ideal Path

36 篇文章 0 订阅
28 篇文章 0 订阅

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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值