码迷,mamicode.com
首页 > 其他好文 > 详细

P2966 [USACO09DEC]Cow Toll Paths G

时间:2020-04-24 01:45:39      阅读:66      评论:0      收藏:0      [点我收藏+]

标签:想法   nod   define   要求   端点   最小   line   www   clu   

题意描述

Cow Toll Paths G

这道题翻译的是真的不错,特别是第一句话

给定一张有 \(n\) 个点 \(m\) 条边的无向图,每条边有边权,每个点有点权。

两点之间的路径长度为所有边权 + 点权的最大值,求 \(q\)\(s\to t\) 的最短路径。

算法分析

数据范围 \(n\leq 250\)和谐数字)Floyd 乱搞没跑了。

但是这道题唯一与普通全源最短路的不同之处在于,这道题要求一个最大点权。

一开始我的想法是二分找最小点权,就是每次只走点权 < mid 的点跑 dijkscal。

但是复杂度好像并不是很低(能过?),所以要有一个更强的优化。(而且不是说好了用 Floyd 吗)

首先,你学习 Floyd 如果仅仅停留在背那 5 行代码的话就太可悲了,Floyd 最重要的是它的原理呀。

为什么最外层循环是 k?因为 k 是中间节点,所以这里有一个性质:

当 Floyd 算法遍历到 \(k\) 时,当前的 \(dis(i,j)\) 除去 \(i,j\) 两个端点外,中途经过的点都 \(<k\)

那么利用这个性质我们可以有一个很高效的算法\(O(n^3)\) 叫高效)

  1. 对于每个点按照点权从小到大来排序。
  2. Floyd 时,最大点权一定是 \((i,j,k)\) 三点中的一个。

然后每次仅边权和答案两个数组分开计算即可。

代码实现

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 300
using namespace std;

int n,m,q,d[N][N],dis[N][N],rank[N];
struct node{
	int nu,id;
}a[N];

int read(){
	int x=0,f=1;char c=getchar();
	while(c<‘0‘ || c>‘9‘) f=(c==‘-‘)?-1:1,c=getchar();
	while(c>=‘0‘ && c<=‘9‘) x=x*10+c-48,c=getchar();
	return x*f;
}

bool cmp(node a,node b){return a.nu==b.nu?a.id<b.id:a.nu<b.nu;}

int main(){
	memset(d,0x3f,sizeof(d));
	memset(dis,0x3f,sizeof(dis));
	n=read(),m=read(),q=read();
	for(int i=1;i<=n;i++)
		a[i].nu=read(),a[i].id=i,d[i][i]=0;
	sort(a+1,a+n+1,cmp);
	for(int i=1;i<=n;i++)
		rank[a[i].id]=i;
	int u,v,w;
	for(int i=1;i<=m;i++)
		u=read(),v=read(),w=read(),d[rank[u]][rank[v]]=d[rank[v]][rank[u]]=min(d[rank[u]][rank[v]],w);
	for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++){
				if(i==j) continue;
				d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
				dis[i][j]=min(dis[i][j],d[i][j]+max(a[k].nu,max(a[i].nu,a[j].nu)));
			}
	for(int i=1;i<=q;i++)
		u=read(),v=read(),printf("%d\n",dis[rank[u]][rank[v]]);
	return 0;
}

完结撒花

P2966 [USACO09DEC]Cow Toll Paths G

标签:想法   nod   define   要求   端点   最小   line   www   clu   

原文地址:https://www.cnblogs.com/lpf-666/p/12764866.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!