POJ 2267 最短路

题目连接: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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值