POJ 1135/ZOJ 1298 Domino Effect

最短路径问题   Dijkstra



题意:

有n个关键骨牌,每两个关键骨牌之间之多有一行普通骨牌,一共有m行骨牌,可以理解成有m条边。从第一张骨牌开始推到,最后一张倒下的骨牌要么是关键骨牌,要么是两张关键骨牌中的一张。



分析:

先用Dijkstra算法求出每张关键牌的最短路径,然后计算每一行倒下的时间,记录关键牌倒下的时间和位置,枚举每一行中间的普通牌倒下的时间和两端的关键牌位置。



这道题警醒我,英语学得不够好!做题看题目不够细心!在POJ上面 WA 8次,换来血的教训!!

WA的原因有以下几点:

1)

if(maxt2 > maxt1) printf("%.1f seconds, and key domino %d and %d.\n\n",maxt2, pos1+1, pos2+1);

2)

if(maxt2 > maxt1) printf("%.1f seconds, between key domino %d and %d.\n\n",maxt2, pos1+1, pos2+1);

3)

if(maxt2 > maxt1) printf("%.1f seconds, between key dominos %d and %d.\n\n",maxt2, pos1+1, pos2+1);



下面放上第九次提交终于血泪中AC的代码:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;

#define MAXN 510
#define INF 1000000

int n,m;
double maxt1,maxt2;
int pos,pos1,pos2,i,j,k;
int _time[MAXN],e[MAXN][MAXN],s[MAXN];

void Solve( ) {
    memset(s, 0, sizeof(s));
    memset(_time, 0, sizeof(_time));
    for(i=0; i<n; i++) {
        _time[i] = e[0][i];
    }
    _time[0] = 0;
    s[0] = 1;
    for(i=1; i<n; i++) {
        int min = INF;
        int u = 0;
        for(j=0; j<n; j++) {
            if(!s[j] && _time[j]<min) {
                u = j;
                min = _time[j];
            }
        }
        s[u] = 1;
        for(k=0; k<n; k++) {
            if(!s[k] && e[u][k]<INF && _time[u]+e[k][u]<_time[k]) {
                _time[k] = _time[u] + e[k][u];
            }
        }
    }
    maxt1 = -INF;
    for(i=0 ;i<n; i++) {
        if(_time[i] > maxt1) {
            maxt1 = _time[i];
            pos = i;
        }
    }
    double t;
    maxt2 = -INF;
    for(i=0; i<n; i++) {
        for(j=0; j<n; j++) {
            t = (_time[i] + _time[j] + e[i][j])/2.0;
            if(e[i][j]<INF && t>maxt2) {
                maxt2 = t;
                pos1 = i;
                pos2 = j;
            }
        }
    }
}

int main( ) {
    int a, b, t, Case = 1;
    while(scanf("%d%d",&n,&m)!=EOF) {
        if(n==0 && m==0) break;
        for(i=0; i<n; i++)
            for(j=0; j<n; j++) {
                e[i][j] = INF;
            }
        for(i=0; i<m; i++) {
            scanf("%d%d%d",&a,&b,&t);
            a--;
            b--;
            e[a][b] = e[b][a] = t;
        }
        Solve();
        printf("System #%d\n", Case++);
        printf("The last domino falls after ");
        if(maxt2 > maxt1) printf("%.1f seconds, between key dominoes %d and %d.\n\n",
                                 maxt2, pos1+1, pos2+1);
        else printf("%.1f seconds, at key domino %d.\n\n", maxt1, pos+1);
    }
    return 0;
}




你可能感兴趣的:(POJ 1135/ZOJ 1298 Domino Effect)