[bzoj1774] [Usaco2009 Dec]Toll 过路费

  Floyd神用法。。。设dis[i][j]表示i点到j点的最短路(只算边权),map[i][j]表示i到j最小费用

  将n个点先按照点权排一下序。。。这样就可以比较方便的求出路径上最大点权了。。。

  因为floyd会枚举到路径上的所有节点(当然也包括最短路径外的= =)所以每次找到松弛节点就尝试着更新一下map(最短路不一定费用最少)。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn=253;
 7 struct point{
 8     int pos,val;
 9 }poi[maxn];
10 int ans[10023],dis[maxn][maxn],map[maxn][maxn];
11 int i,j,k,n,m,K,tot,a,b,d,num;
12 int ra;char rx;
13 inline int read(){
14     rx=getchar();ra=0;
15     while(rx<'0'||rx>'9')rx=getchar();
16     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
17 }
18 bool cmp(point a,point b){return a.val<b.val;}
19 int main(){
20     n=read();m=read();K=read();
21     for(i=1;i<=n;i++)poi[i].val=read(),poi[i].pos=i;
22     sort(poi+1,poi+1+n,cmp);
23     for(i=1;i<=n;i++)memset(dis[i],50,(n+1)<<2),memset(map[i],50,(n+1)<<2),dis[i][i]=0;
24     for(i=1;i<=m;i++)a=read(),b=read(),d=read(),dis[b][a]=dis[a][b]=min(dis[a][b],d);
25     for(k=1,d=poi[k].pos;k<=n;k++,d=poi[k].pos)
26     for(i=1,a=poi[i].pos;i<=n;i++,a=poi[i].pos)for(j=1,b=poi[j].pos;j<=n;j++,b=poi[j].pos){
27             if(dis[a][d]+dis[d][b]<dis[a][b])dis[a][b]=dis[a][d]+dis[d][b];
28             map[a][b]=min(map[a][b],dis[a][b]+poi[max(i,max(j,k))].val);
29         }
30     for(i=1;i<=K;i++)a=read(),b=read(),printf("%d\n",map[a][b]);
31     return 0;
32 }
View Code

 

posted @ 2015-12-23 18:52  czllgzmzl  阅读(651)  评论(0编辑  收藏  举报