UVA_10801
这个是一个求最短路的题目。首先我们用邻接矩阵G[i][j]表示第i个电梯是否可以到第j层,然后便用队列优化的Bellman-Ford算法去求解最短路即可。
需要注意的是,在求最短路时枚举的必须是可以到达该点的电梯。同时,为了运算方便,我们可以假设第一次乘电梯时也需要等60s,最后再从结果中除掉这多余的60s即可,但由于数据中存在k=0的情况,所以在除去60s时要加一个判断。
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
#define INF 1000000000
int n, k, T[10], G[10][110];
int d[110], q[110], inq[110];
char b[1000];
int init()
{
int i, j, p, e, temp;
memset(G, 0, sizeof(G));
e = 0;
while(gets(b)!=NULL)
{
sscanf(b, "%d%d", &n, &k);
gets(b);
p = strlen(b);
for(i = 0, j = 0; j < p; j ++)
if(isdigit(b[j]))
{
sscanf(&b[j], "%d", &temp);
T[i ++] = temp;
while(isdigit(b[j]))
j ++;
}
for(i = 0; i < n; i ++)
{
gets(b);
p = strlen(b);
for(j = 0; j < p; j ++)
if(isdigit(b[j]))
{
sscanf(&b[j], "%d", &temp);
while(isdigit(b[j]))
j ++;
G[i][temp] = 1;
}
}
return 1;
}
return 0;
}
int check()
{
int i, j, temp, u, v, front, rear;
for(i = 1; i <= 100; i ++)
d[i] = INF + 1;
d[0] = 0;
front = rear = 0;
memset(inq, 0, sizeof(inq));
q[rear ++] = 0;
inq[0] = 1;
while(front != rear)
{
u = q[front ++];
inq[u] = 0;
if(front > 101)
front = 0;
for(i = 0; i < n; i ++)
if(G[i][u])
for(v = 1; v <= 100; v++)
if(G[i][v])
{
temp = d[u] + T[i] * abs(u - v) + 60;
if(temp < d[v])
{
d[v] = temp;
if(! inq[v])
{
q[rear ++] = v;
inq[v] = 1;
if(rear > 101)
rear = 0;
}
}
}
}
if(d[k] > INF)
return -1;
else if(k == 0)
return 0;
else
return d[k] - 60;
}
int main()
{
int ans;
while(init())
{
ans = check();
if(ans < 0)
printf("IMPOSSIBLE\n");
else
printf("%d\n", ans);
}
return 0;
}