3
10
2016
0

[BZOJ1774] [Usaco2009 Dec]Toll 过路费

这题其实一开始看的时候我是不会做的……

考虑Floyd,f[i][j]=min(f[i][j],f[i][k]+f[k][j]);

那么我们考虑k的转移顺序,如果让k的点权严格上升,那么转移时增加的点权必定为v[i],v[j]或者v[k]。

那么直接Floyd就可以了。

以后想问题时一定要弄明白算法的本质,不然就会困难重重……

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int n,m,K,v[255],dis[255][255],ans[255][255];

struct Point{
int x,y;
friend bool operator<(Point x,Point y){return x.y<y.y;}
}p[255];

int main(){
freopen("1774.in","r",stdin);
freopen("1774.out","w",stdout);
scanf("%d %d %d",&n,&m,&K);
memset(dis,127/3,sizeof(dis));
memset(ans,127/3,sizeof(ans));
for(int i=1;i<=n;i++){
	scanf("%d",&p[i].y);
	p[i].x=i;
	v[i]=p[i].y;
}
for(int i=1;i<=m;i++){
	int x,y,z;
	scanf("%d %d %d",&x,&y,&z);
	dis[x][y]=min(dis[x][y],z);
	dis[y][x]=min(dis[y][x],z);
}
sort(p+1,p+n+1);
for(int k=1;k<=n;k++){
	int l=p[k].x;
    for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			dis[i][j]=min(dis[i][j],dis[i][l]+dis[l][j]);
			ans[i][j]=min(ans[i][j],dis[i][j]+max(max(v[i],v[j]),v[l]));
		}
    }
}
for(int i=1;i<=K;i++){
	int x,y;
	scanf("%d %d",&x,&y);
	printf("%d\n",ans[x][y]);
}
return 0;
}
Category: BZOJ | Tags: OI bzoj | Read Count: 485

登录 *


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

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com