[floyd]Day 3 提高组模拟C组 T4 过路费

题目链接

https://www.luogu.org/problemnew/show/P2966

题目大意

有一张无向图,边有边权,点有点权, x y 点的代价为中间所有边权的和+点权的最大值

解题思路

对点权排序,使点权具有单调性,然后 f l o y d

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int dis[251][251],ans[251][251],nid[251],n,m,q,x,y,z;
struct node{int w,id;}a[251];
bool cmp(node x,node y){return x.w<y.w;}
int main()
{
    freopen("toll.in","r",stdin);
    freopen("toll.out","w",stdout);
    memset(dis,127/3,sizeof(dis));
    memset(ans,127/3,sizeof(ans));
    scanf("%d%d%d",&n,&m,&q);
    for(int i=1;i<=n;i++) scanf("%d",&a[i].w),a[i].id=i;
    sort(a+1,a+1+n,cmp);
    for(int i=1;i<=n;i++) nid[a[i].id]=i;//存下新的序号
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&x,&y,&z);
        dis[nid[x]][nid[y]]=dis[nid[y]][nid[x]]=min(z,dis[nid[y]][nid[x]]);//用新的序号来进行
    }
    for(int k=1;k<=n;k++)
     for(int i=1;i<=n;i++)
      for(int j=1;j<=n;j++)
       {
        dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
        ans[i][j]=min(ans[i][j],dis[i][j]+max(a[i].w,max(a[j].w,a[k].w)));//因为排了序后所有元素具有单调性因此点权即为i,j,k的最大值
       }
    while(q--)
    {
        scanf("%d%d",&x,&y);
        printf("%d\n",ans[nid[x]][nid[y]]);
    }
}

猜你喜欢

转载自blog.csdn.net/xuxiayang/article/details/80960752
今日推荐