2020.3.18普及C组 过路费(toll)【纪中】【Floyd】【点权】

44 篇文章 0 订阅

巧妙的 F l o y d Floyd Floyd

我们先把点权排序,这样就能符合 F l o y d Floyd Floyd的性质,我们就可以直接一边跑 F l o y d Floyd Floyd一边比较点权求最大了。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int f[1010][1010],w[1010],bq[1010][1010];
int n,m,q,ax,ay,x,y,z;
struct node
{
  int c,id;
}d[1010];
bool cmp(node a,node b)
{
    return a.c==b.c?a.id<b.id:a.c<b.c;
}
int main()
{
	freopen("toll.in","r",stdin);
    freopen("toll.out","w",stdout);
	cin>>n>>m>>q;
    for(int i=1; i<=n; i++)
     {
	   scanf("%lld",&d[i].c);
	   d[i].id=i;
     }
    sort(d+1,d+1+n,cmp);
    for(int i=1; i<=n; i++)
	   w[d[i].id]=i;
	for(int i=1; i<=n; i++)
	 for(int j=1; j<=n; j++)
	  f[i][j]=bq[i][j]=1e9;
    for(int i=1; i<=n; i++)
	   bq[i][i]=0;
	for(int i=1; i<=n; i++)
	 for(int j=1; j<=f[i]; j++)
	 if(bq[i][j]==w[i])
	   f[i][j]=bq[i][j]+w[i];
    for(int i=1; i<=m; i++)
     {
        scanf("%lld%lld%lld",&x,&y,&z);
        x=w[x];
		y=w[y];
        bq[x][y]=min(bq[x][y],z);   //预处理边权
		bq[y][x]=bq[x][y];
     }
    for(int k=1; k<=n; k++)
     for(int i=1; i<=n; i++)
      for(int j=1; j<=n; j++)
       {
          bq[i][j]=min(bq[i][j],bq[i][k]+bq[k][j]);  //Floyd
          f[i][j]=min(bq[i][j]+max(d[i].c,max(d[j].c,d[k].c)),f[i][j]);  //点权比较
       }
    for(int i=1; i<=q; i++)
     {
        scanf("%lld%lld",&ax,&ay);
        ax=w[ax];
		ay=w[ay];
	    cout<<f[ax][ay]<<endl;
     }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值