背景
9.19是青子的生日...
而在那日晚,基德发出了盗窃"忧郁的生日"的预告函.
快斗在两难的抉择下,最终决定:以最快速度将"忧郁的生日"收入囊中,再赶去为青子表演魔术--这是他对青子的允诺.
题目描述
"忧郁的生日"被保存在一个深不可测的大楼里.而从大门到最里面的房间有无数条路径.整个大楼可以被看做一个巨大的无向图,有些
房间之间有路,而有些没有.每条路要消耗基德不一样的时间.在最里面的房间内存放着"忧郁的生日".这块宝石被一层密码锁保护着.
打开这层密码锁也需要一段时间.假设基德盗窃时没有人来干扰(警卫都干什么吃的).给出基德开始盗窃的时间,整个大楼中连通的情
况以及打开这个密码锁的时间.求出快斗能对青子允诺到达生日会场的最早时间.若此时间晚于24:00则输出"Sad".
输入格式
输入文件共k+3行.
第一行,是基德开始盗窃的时间.格式为形如"xx:xx"的24小时制形式(如13:00);
第二行到第k+2行为大楼的连通情况.
第二行共2个整数n,k.n为房间总数,共k对房间之间有路径.进口为1号房间,"忧郁的生日"存放在n号房间里.
第三行到第k+2行,每行共3个整数a,b,c.表示a号和b号房间之间有路径,该路径费时为c分钟.
第k+3行为打开密码锁的时间,格式为"x min/second/hour"表示打开密码锁需要x分钟/秒/小时.
输出格式
输出共一行,输出快斗能允诺青子的最早时间,格式如同输入中的开始盗窃时间格式"xx:xx",24小时制.若最早时间超过24:00则输出
"Sad".
样例输入
17:00
3 3
1 2 1
2 3 1
1 3 4
3min
样例输出
17:05
提示
数据保证一定能抵达中心房间。需要注意的是,输入数据中可能会出现0号结点。这些数据均需被忽略不计。而输入中开始时间必定
遵守"xx:xx"格式,如"05:00";但输出中你必须这样表示:"5:00"而不应出现一开始的“0”。
来源
From 玛维-影之歌
永远守望vijos...
解题思路
最短路走一波。。。
#include <stdio.h>
#define MAXN 1010
const int inf = 99999999;
int n, m, vis[MAXN], dis[MAXN], map[MAXN][MAXN];
void Dijkstra(int s)
{
int k, minn;
for (int i = 1; i <= n; i++)
{
vis[i] = 0;
dis[i] = inf;
}
dis[s] = 0;
for (int i = 0; i < n; i++)
{
k = s;
minn = inf;
for (int j = 1; j <= n; j++)
if (!vis[j] && dis[j] < minn)
minn = dis[k = j];
vis[k] = 1;
for (int j = 1; j <= n; j++)
if (map[k][j] < inf)
if (!vis[j] && dis[j] > dis[k] + map[k][j])
dis[j] = dis[k] + map[k][j];
}
}
int main()
{
char str[10];
int ah, am, as, u, v, w;
while (~scanf("%d:%d", &ah, &am))
{
as = 0;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
map[i][j] = inf;
for (int i = 0; i < m; i++)
{
scanf("%d%d%d", &u, &v, &w);
if (u && v)
map[u][v] = map[v][u] = w;
}
scanf("%s", str);
for (int i = 0; str[i]; i++)
{
if (str[i] >= '0' && str[i] <= '9')
as = as * 10 + str[i] - '0';
else if (str[i] != 's')
{
if (str[i] != 'm')
as *= 3600;
else as *= 60;
break;
}
else break;
}
Dijkstra(1);
as += ah * 3600 + (am + dis[n]) * 60;
if (as > 24 * 3600)
printf("Sad\n");
else printf("%d:%02d\n", as / 3600, as % 3600 / 60);
}
return 0;
}