1084: [SCOI2005]最大子矩阵
1787: [Ahoi2008]Meet 紧急集合

1774: [Usaco2009 Dec]Toll 过路费

高橋直樹 posted @ 2013年3月22日 15:19 in BZOJ with tags bzoj usaco , 1174 阅读

http://www.lydsy.com/JudgeOnline/problem.php?id=1774

RunID User Problem Result Memory Time Language Code_Length Submit_Time
373994 Liu_Ts 1774 Accepted 1300 kb 304 ms C++/Edit 1013 B 2013-03-22 14:42:09

 

题意

一个图,每条边有边权,每个点也有点权,

定义两个点之间的费用为,两点之间的路径长度加上路径上最大的一个点权。

询问任意两个点对的最小费用。

题解

一看到是求任意点对的费用,就要floyd

然后floyd的性质保证当过渡点循环到k时,所有经过的点的编号<=k;

于是,我们按点权从小到大排序后,floyd。

 

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=251;
int f[N][N],ans[N][N],num[N],n,m,p;
struct node
{
	int w,n;
}a[N];
inline bool cmp(node a,node b)
{
	return a.w<b.w;
}
int main()
{
	memset(f,63,sizeof(f));
	memset(ans,63,sizeof(ans));
	scanf("%d%d%d",&n,&m,&p);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i].w);a[i].n=i;
		f[i][i]=0;
	}
	sort(a+1,a+1+n,cmp);
	for(int i=1;i<=n;i++)	num[a[i].n]=i;
	int x,y,z;
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&x,&y,&z);
		x=num[x];y=num[y];
		f[x][y]=f[y][x]=min(f[x][y],z);
	}
	for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
			{
				f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
				ans[i][j]=min(ans[i][j],f[i][j]+max(a[k].w,max(a[i].w,a[j].w)));
			}
	for(int i=1;i<=p;i++)
	{
		scanf("%d%d",&x,&y);
		printf("%d\n",ans[num[x]][num[y]]);
	}
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter