题目链接
https://www.luogu.org/problemnew/show/P2966
题目大意
有一张无向图,边有边权,点有点权, 到 点的代价为中间所有边权的和+点权的最大值
解题思路
对点权排序,使点权具有单调性,然后
代码
#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]]);
}
}