不错的最短路径题目。

/*
*State: POJ1135     Accepted    1204K    0MS    C++    1854B
*题目大意:
*        有一个多米诺骨牌的游戏,我们知道有关键骨牌和普通骨牌,将
*        关键骨牌推倒之后,整个骨牌阵就会倒下,推动其他的关键骨牌,
*        其中推倒关键骨牌A使的关键骨牌B也倒,需要一定的时间,所以
*        本题要求求出最后一个倒的骨牌的位置,及其时间
*解题思路:
*        想一下结果,其实最后一个骨牌倒的位置只有2种情况,要么就是
*        在关键骨牌的位置,要么就是在两个关键骨牌之间。之后就好做了,
*        如果倒在关键骨牌,那么只要计算各个关键骨牌的最短路即可。如果
*        倒在两个关键骨牌之间,那么就是两个关键骨牌的最短路的和+两个
*        关键骨牌的距离再除以2.
*解题感想:
*        感觉这一道题真的出得挺好的,一开始还想到用搜索呢,但是其实
*        如果考虑到了该问题的本质,由骨牌的最终状态考虑回来,那么就
*        可以想到用最短路了。
*/
View Code
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

const int MAXN = 505;
const int inf = 0x3f3f3f3f;
int Map[MAXN][MAXN];
vector<int> ind;
double Max;

void init()
{
    ind.clear();
    Max = -1;
    for(int i = 0; i < MAXN; i++)
        for(int j = 0; j < MAXN; j++)
            Map[i][j] = inf;
}

int spfa(int s, int n)
{
    int inQ[MAXN] = {0};
    int dis[MAXN];
    for(int i = 0; i <= n; i++)
        dis[i] = inf;

    queue<int> Q;
    Q.push(s);
    inQ[s] = 1;
    dis[s] = 0;

    while(!Q.empty())
    {
        int pre = Q.front();
        inQ[pre] = 0;
        Q.pop();

        for(int i = 1; i <= n; i++)
        {
            int w = Map[pre][i];
            if(Map[pre][i] != inf && dis[i] > dis[pre] + w)
            {
                dis[i] = dis[pre] + w;
                if(!inQ[i])
                {
                    Q.push(i);
                    inQ[i] = 1;
                }
            }
        }
    }
    
    for(int i = 1; i <= n; i++)
    {
        if(dis[i] > Max)
        {
            Max = dis[i];
            ind.clear();
            ind.push_back(i);
        }    
    }

    for(int i = 1; i <= n; i++)
        for(int j = i + 1; j <= n; j++)
        {
            if(Map[i][j] != inf)
            {
                double t = (dis[i] + dis[j] + Map[i][j]) / 2.0;
                if(t > Max)
                {
                    Max = t;
                    ind.clear();
                    ind.push_back(i);
                    ind.push_back(j);
                }
            }
        }
    return 0;
}

int main(void)
{
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
#endif

    int n, m, cas_c = 1;
    while(scanf("%d %d",&n, &m), n || m)
    {
        int u, v, w;
        init();
        for(int i = 0; i < m; i++)
        {
            scanf("%d %d %d", &u, &v, &w);
            Map[u][v] = Map[v][u] = w;
        }
        spfa(1, n);
        printf("System #%d\n", cas_c++);
        if(ind.size() == 1)
            printf("The last domino falls after %.1lf seconds, at key domino %d.\n", Max, ind[0]);
        else if(ind.size() == 2)
            printf("The last domino falls after %.1lf seconds, between key dominoes %d and %d.\n", Max, ind[0], ind[1]);
        printf("\n");
    }
    return 0;
}
posted on 2012-09-02 15:42  cchun  阅读(363)  评论(0编辑  收藏  举报