UVa 1599 - Ideal Path <两次BFS>

两个月前就搞这道题,昨天翻出来直接修改的当时的超时代码,经历了多种错误,最后终于还是AC了。

这道题还是挺好的一道题,需要正反两次BFS,需要加各种防超时的判断。实际上还是考差对问题的理解,什么时候应该剪枝,什么地方不必重复判断。

第一次反着BFS,找到各点到终点的最短距离。第二次正着BFS,顺着距离递减的方向,按照颜色小的优先的方法走。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <climits>
#include <queue>
#define MAXN 102400
using namespace std;

int n, m;
vector<int> road[MAXN], col[MAXN];
int d[MAXN], ans[MAXN];
bool vis[MAXN];

void clr()
{
    for(int i = 0; i < MAXN; i++)
        road[i].clear(), col[i].clear();
    memset(d, -1, sizeof(d));
    memset(ans, 0, sizeof(ans));
    memset(vis, false, sizeof(vis));
}

void BFS1()
{
    queue<int> qu;
    qu.push(n);
    d[n] = 0;
    while(!qu.empty()){
        int u = qu.front(); qu.pop();
        for(size_t i = 0; i != road[u].size(); i++)
            if(d[road[u][i]]==-1){
                int v = road[u][i];
                d[v] = d[u] + 1;
                if(v == 1) return;
                qu.push(v);
            }
    }
}

void BFS2()
{
    queue<int> qu;
    qu.push(1);
    while(!qu.empty()){
        int u = qu.front(); qu.pop();
        if(u==n) return;
        int curd = d[u];
        int minclr = INT_MAX;
        for(size_t i = 0, sz = road[u].size(); i < sz; ++i)
            if(d[road[u][i]] + 1 == curd)
                minclr = min(minclr, col[u][i]);
        if(!ans[curd] || minclr<=ans[curd]) ans[curd] = minclr;
        else continue;
        for(size_t i = 0, sz = road[u].size(); i < sz; ++i){
            int v = road[u][i];
            if(!vis[v] && col[u][i]==minclr && d[v]+1==curd)
                qu.push(v), vis[v] = true;
        }
    }
}

int main()
{
    //freopen("in.txt", "r", stdin);
    while(clr(), ~scanf("%d %d", &n, &m)){
        while(m--){
            int a, b, c; scanf("%d %d %d", &a, &b, &c);
            road[a].push_back(b); col[a].push_back(c);
            road[b].push_back(a); col[b].push_back(c);
        }
        BFS1(); BFS2();
        printf("%d\n", d[1]);
        for(int i = d[1]; i >= 1; --i){
            if(i==d[1]) printf("%d", ans[i]);
            else printf(" %d", ans[i]);
        }
        printf("\n");
    }
    return 0;
}


posted @ 2015-02-03 15:05  Popco  阅读(227)  评论(0编辑  收藏  举报