uva 1599 (两次bfs)

本文深入探讨了使用双BFS算法解决特定图论问题的方法。首先介绍了如何通过第一次BFS从终点逆向寻找各节点到终点的最短路径,接着阐述了如何在第二次BFS中确定最小颜色值并进行有效节点遍历,最终实现高效路径搜索。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述
思路:第一遍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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值