一开始直接想跑最短路
看了看询问次数
放弃了
然后果断看了题解
Floyd
用啥都不会用它的好吗
平常的最劣选择
但是
它就是正解
Floyd的原理
就是枚举中点
这里
因为出题人
已经把询问排好了序
只需要判断中点
有没有重建完成
把它加入图中
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
using namespace std;
struct maki
{
int p1,p2,tim;
}que[50005];
int dis[205][205],i,j,k,p,n,m,ti[205],x,y,t,a,b,w,vis[205],q;
int main()
{
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
for(j=0;j<n;j++)
dis[i][j]=1e6;
for(i=0;i<n;i++) scanf("%d",&ti[i]);
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&w);
dis[a][b]=w;
dis[b][a]=w;
}
scanf("%d",&q);
for(i=1;i<=q;i++)
{
scanf("%d%d%d",&x,&y,&t);
que[i].p1=x;
que[i].p2=y;
que[i].tim=t;
}
for(p=1;p<=q;p++)
{
x=que[p].p1;
y=que[p].p2;
if(ti[x]>que[p].tim||ti[y]>que[p].tim)
{
printf("-1\n");
continue;
}
for(k=0;k<n;k++)
if((ti[k]<=que[p].tim)&&(!vis[k]))
{
vis[k]=1;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(i!=j&&j!=k&&k!=i)
dis[i][j]=min(dis[i][j],dis[i][k]+dis[j][k]);
}
if(dis[x][y]>=1e6) printf("-1\n");
else printf("%d\n",dis[x][y]);
}
return 0;
}