UVa 10801 Lifting Hopping (Dijsltra)

来源:互联网 发布:淘宝国际转运cn dpd 编辑:程序博客网 时间:2024/05/21 09:13

这道题的建图,比较有讲究,开始想了很久,到底是怎么建图能体现现出换电梯需要六十秒!后来参考了别人的思路,就是只要一条边走到头,就换电梯,也就是换边就是换电梯。

建图,把每个电梯能到达的楼层,两两之间有一条边,如果有其他电梯的这条边更短,选择更短的。

每次换边的时候,要注意加60,因为需要60秒;最后结构要-60,因为第一次进电梯不需要60;如果去第0层,就是另外处理,是0,否则正常输出的是-60

代码:

#include <cstdio>#include <cstring>#include <queue>#include <algorithm>using namespace std;const int N = 110;const int INF = 10000000;int n, k, cnt;int g[N][N], d[N], t[10], tmp[N];bool vis[N];void build( int ss ) {    for ( int i = 0; i < cnt; ++i )         for ( int j = i + 1; j < cnt; ++j ) {            int dist = abs( tmp[j] - tmp[i] ) * t[ss], x = tmp[i], y = tmp[j];            if ( dist < g[x][y] ) g[x][y] = g[y][x] = dist;        }}int dij( ) {    memset( vis, 0, sizeof(vis));    d[0] = 0;    for ( int u = 0; u < 100; ++u ) {        int mi = INF, v;        for ( int i = 0; i < 100; ++i ) if ( !vis[i] && mi > d[i] ) mi = d[i], v = i;        vis[v] = 1;        for ( int i = 0; i < 100; ++i ) if ( !vis[i] && d[i] > d[v] + g[v][i] +60 ) d[i] = d[v] + g[v][i] + 60;    }    return d[k];}int main() {    while ( scanf("%d%d", &n, &k) != EOF ) {        for ( int i = 0; i < n; ++i ) scanf("%d", &t[i]);        for ( int i = 0; i < N; d[i] = INF, ++i ) for ( int j = 0; j < N; ++j ) g[i][j] = INF;        for ( int i = 0; i < n; ++i ) {            char ch;            cnt = 0;            while ( 1 ) {                scanf("%d%c", &tmp[cnt++], &ch);                if ( ch == 0xa ) break;            }            build( i );        }        int ans = dij();        if ( ans == INF ) printf("IMPOSSIBLE\n");        else printf("%d\n", k == 0 ? 0 : ans-60);    }}