HDU4571 Travel in time

#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<queue>

using namespace std;

const int inf=1<<29;  
const int maxn=102;///城市数量  
const int maxm=505;///时间花费  
int T,n,m,t,s,e,cas=1;  
int map[maxm][maxn];  
int dp[maxm][maxm],pos[maxn];  
struct node  
{  
	int val,cos,id;  
	friend bool operator<(node x,node y)  
	{  
		return x.val<y.val;  
	}  
} p[maxn];  

void read()  
{  
	int i,j,u,v,c;  
	cin>>n>>m>>t>>s>>e;  
	memset(pos,0,sizeof(pos));  
	for(i=0; i<n; i++)
		cin>>p[i].cos;  
	for(i=0; i<n; i++)
		cin>>p[i].val,p[i].id=i;  
	sort(p,p+n);  
	for(i=0; i<n; i++)
		pos[p[i].id]=i;  
	s=pos[s],e=pos[e];  
	for(i=0; i<n; i++)  
	{  
		for(j=0;j<n;j++)
		{
			map[i][j]=inf;
			map[j][i]=inf;
		}
		map[i][i]=0;  
	}  
	for(i=0; i<n; i++)  
	{  
		for(j=0; j<=t; j++)
			dp[i][j]=0;  
	}  
	while(m--)  
	{  
		cin>>u>>v>>c;  
		u=pos[u],v=pos[v];  
		map[u][v]=map[v][u]=min(c,map[u][v]);  
	}  
}  

void floyd()  
{  
	int i,j,k;  
	for(k=0; k<n; k++)  
		for(i=0; i<n; i++)  
			for(j=0; j<n; j++)  
				map[i][j]=min(map[i][j],map[i][k]+map[k][j]);  
}  

int solve()  
{  
	int i,j,k,tmp,ans=0;  
	if(map[s][e]>t)
		return 0;  
	for(i=0; i<n; i++)//到第i个点,最少时间花费下的满意值  
	{  
		for(j=map[s][i]+p[i].cos; j<=t; j++)  
			dp[i][j]=p[i].val;  
	}  
	for(i=0; i<n; i++)//e在游览路径中  
	{              
		for(j=0; j<i; j++)  
		{  
			if(p[i].val>p[j].val)  
			{  
				int key=map[j][i]+p[i].cos+map[s][j];  
				for(k=t-key;k>=0; k--)  
				{  
					tmp=k+map[s][j];  
					dp[i][key+k]=max(dp[j][tmp]+p[i].val,dp[i][key+k]);  
				}  
			}  
		}  
	}  
	ans=dp[e][t];//e在游览路径中的最大值  
	for(i=0; i<n; i++)//e不在游览路径中的最大值  
	{  
		if(i!=e)  
		{  
			if(t-map[i][e]>=map[s][i])  
			{  
				ans=max(ans,dp[i][t-map[i][e]]);  
			}  
		}  
	}  
	return ans;  
}  

int main()  
{  
	cin>>T;  
	while(T--)  
	{  
		read();  
		floyd();  
		printf("Case #%d:\n%d\n",cas++,solve());  
	}  
	return 0;  
}  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值