题目连接:http://poj.org/problem?id=2267
悲剧的题目,WA了n天,数据处理很变态,要拿着边作为新的点再建边,建过边之后就是简单的最短路了,在初始化的时候不小心把边初始化为0了(应该是起点的),几乎想放弃了,又AC了。。代码如下:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<map>
using namespace std;
#define MAX 1005
#define CLR(arr,v) memset(arr,v,sizeof(arr))
struct Trie
{
int index;
struct Trie *next[53];
}tr[MAX];
int pos,len;
int insert(string str)
{
struct Trie *root;
root = &tr[0];
for(int i = 0;i < str.size();++i)
{
if(!(*root).next[str[i] - 'a'])
(*root).next[str[i] - 'a'] = &tr[++pos];
root = (*root).next[str[i] - 'a'];
if(i == str.size() - 1)
{
if(!(*root).index) (*root).index = ++len;
return (*root).index;
}
}
}
int mapp[MAX][MAX],dis[MAX],res;
struct nodes
{
int start,des,st,et;
}node[MAX];
struct edges
{
int begin,end,v,b,e;
}ed[MAX];
int ll;
bool bellman_ford(int s,int e,int n)
{
for(int i = 0;i < n;++i)
if(node[i].start == s)
dis[i] = 0; //初始化起点
for(int i = 1;i <= n;++i)
for(int j = 0;j < ll;++j)
{
if(dis[ ed[j].begin ] + ed[j].v < dis[ ed[j].end ])
dis[ ed[j].end ] = dis[ ed[j].begin ] + ed[j].v;
}
res = INT_MAX / 2;
for(int i = 0;i < n;++i)
if(node[i].des == e && dis[i] < res) res = dis[i]; //如果边的终点是目的地
return res == INT_MAX/2 ? false : true;
}
void init()
{
pos = len = 0;
ll = res = 0;
CLR(ed,0); CLR(tr,0);
CLR(mapp,0); CLR(node,0);
for(int i = 0;i < MAX;++i)
dis[i] = INT_MAX / 2;
}
int main()
{
//freopen("1.txt","r",stdin);
int T;
char str1[40],str2[40];
scanf("%d",&T);
for(int k = 1;k <= T;++k)
{
init();
int t,st,time,l = 0;
scanf("%d",&t);
for(int i = 0;i < t;++i)
{
scanf("%s %s %d %d",str1,str2,&st,&time);
st %= 24;
if(!(st <= 6 && st + time <= 6 || st >= 18 && st + time <= 30)) continue; //判断路是否可走
int u = insert(str1),v = insert(str2);
node[l].start = u;
node[l].des = v;
node[l].st = st;
node[l++].et = (st + time) % 24;
}
scanf("%s %s",str1,str2);
int leng = len;
int s = insert(str1),e = insert(str2);
int en,f = 0;
printf("Test Case %d.\n",k);
if(s == e) //起点为终点
{
printf("Vladimir needs %d litre(s) of blood.\n",res);
continue;
}
if(s > leng || e > leng)//起点或终点不是已出现的城市
{
printf("There is no route Vladimir can take.\n");
continue;
}
for(int i = 0;i < l;++i)
for(int j = 0;j < l;++j)
{
if(node[i].des == node[j].start)
{
int k = 0;
if(node[i].et <= 6 && node[j].st >= 18 || (node[i].et >= 18 && node[j].st >= 18 || node[i].et <= 6 && node[j].st <= 6) && node[i].et > node[j].st)
//如果终点城市的出发时间在到达该城市时间之前,需要等一天
k = 1;
ed[ll].begin = i;
ed[ll].end = j;
ed[ll++].v = k;
}
}
if(bellman_ford(s,e,l))
printf("Vladimir needs %d litre(s) of blood.\n",res);
else
printf("There is no route Vladimir can take.\n");
}
return 0;
}