又是一道题搞了一晚上。。泪奔,刚开始直接每条铁路遍历用最短路,前面小数据可以过,最后一组数据超大!直接TLE了。。苦思半天没有优化思路,看了看大神题解,一句话点醒了,先正向dijkstra求最早到达时间,然后根据这个时间反向dijkstra求最晚出发时间,这样两次就能求出答案了,果然犀利啊,膜拜
#include<cstdio>
#include<map>
#include<vector>
#include<string>
#include<climits>
#include<cstring>
using namespace std;
namespace
{
vector<map<int, int> > V;
vector<string> cityname;
void dijkstra(int src, int dst, int n, int time)
{
bool known[100];
int d[100];
int depart = INT_MAX, end = INT_MAX;
for (size_t t = 0; t < V.size(); t++)
if (V[t].find(src) != V[t].end() && V[t][src] >= time
&& V[t][src] < depart)
depart = V[t][src];
memset(known, 0, sizeof(known));
for (int i = 0; i < n; i++)
d[i] = INT_MAX;
d[src] = depart;
int now = src;
while (true)
{
known[now] = true;
for (size_t i = 0; i < V.size(); i++)
if (V[i].find(now) != V[i].end())
{
int dn = d[now];
for (map<int, int>::iterator it = V[i].begin();
it != V[i].end(); it++)
{
int city = (*it).first;
int arrive = (*it).second;
if (!known[city] && arrive >= dn && arrive < d[city])
d[city] = arrive;
}
}
int mind = INT_MAX;
for (int i = 0; i < n; i++)
if (!known[i] && d[i] < mind)
{
now = i;
mind = d[i];
}
if (now == dst)
{
end = d[now];
break;
}
if (mind == INT_MAX)
break;
}
if (end == INT_MAX)
{
puts("No connection\n");
return;
}
memset(known, 0, sizeof(known));
memset(d, -1, sizeof(d));
d[dst] = end;
now = dst;
while (true)
{
known[now] = true;
for (size_t i = 0; i < V.size(); i++)
if (V[i].find(now) != V[i].end() && V[i][now] <= d[now])
{
int dn = d[now];
for (map<int, int>::iterator it = V[i].begin();
it != V[i].end(); it++)
{
int city = (*it).first;
int arrive = (*it).second;
if (!known[city] && arrive <= dn && arrive > d[city])
d[city] = arrive;
}
}
int mind = -1;
for (int i = 0; i < n; i++)
if (!known[i] && d[i] > mind)
{
now = i;
mind = d[i];
}
if (now == src)
{
printf("%-10s%02d%02d %s\n", "Departure", d[now] / 60,
d[now] % 60, cityname[src].c_str());
printf("%-10s%02d%02d %s\n", "Arrival", end / 60, end % 60,
cityname[dst].c_str());
putchar('\n');
break;
}
}
}
}
int main()
{
int C, cs = 0;
map<string, int> city;
char ch[20];
while (scanf("%d", &C), C)
{
getchar();
printf("Scenario #%d\n", ++cs);
city.clear();
cityname.clear();
for (int i = 0; i < C; i++)
{
scanf("%s", ch);
string s(ch);
city[s] = i;
cityname.push_back(s);
}
int T, ti, time;
scanf("%d", &T);
V.clear();
while (T--)
{
scanf("%d", &ti);
map<int, int> m;
while (ti--)
{
scanf("%d %s", &time, ch);
string name(ch);
m[city[name]] = (time / 100) * 60 + time % 100;
}
V.push_back(m);
}
scanf("%d", &time);
time = (time / 100) * 60 + time % 100;
int src, dst;
scanf("%s", ch);
string ss(ch);
src = city[ss];
scanf("%s", ch);
string dd(ch);
dst = city[dd];
dijkstra(src, dst, C, time);
}
return 0;
}