私はこの質問を感じる非常に巧妙なアイデアの巧妙な使用\(フロイド\)は、この問題をうまくすると考えられている、と言っている、\(\)将来的にこの問題出て、私は自分がする感じ(\しますフロイド\)の詳細を知るために、物質の。
考え
実際には、我々はすべて知っている\(フロイド\)限り標準コード
for(int k=1;k<=n;++k)
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
だから、この質問のために、すべての村のために、我々は時間の持っている\(time_iを\) 、現在の問い合わせ時間に等しいよりだけ少ない時間を修正するために、各ルートに接続されている唯一の二つの村(注:お問い合わせ時間は単調性が保証されます)増加し、このルートは有効です。
各修理村のために\(私は\) 、我々はすべて添付することができます\(私は\)最短村の村の更新を再度、コードは次のように実装されています
void update(int k)
{
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
f[i][j]=f[j][i]=min(f[i][j],f[i][k]+f[k][j]);
}
はい、通常で\(フロイド\)ほぼ同じであるが、我々は、別の更新与えられ\(K \)ポイント
\(コード:\)を
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int tot,n,m;
int t[211],f[211][211];
bool book[211];
void update(int k)
{
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
f[i][j]=f[j][i]=min(f[i][j],f[i][k]+f[k][j]);
}
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
int inf=1e9;
scanf("%d %d",&n,&m);
for(int i=0;i<n;++i) scanf("%d",&t[i]);
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
f[i][j]=inf;
for(int i=1;i<=m;++i)
{
int u,v,w;
scanf("%d %d %d",&u,&v,&w);
f[u][v]=f[v][u]=w;
}
int Q,now=0;
scanf("%d",&Q);
for(int i=1;i<=Q;++i)
{
int x,y,ta;
scanf("%d %d %d",&x,&y,&ta);
while(t[now]<=ta && now<n)
{
book[now]=true;
update(now);
++now;
}
if(t[x]>ta || t[y]>ta || f[x][y]==inf) printf("-1\n");
else printf("%d\n",f[x][y]);
}
return 0;
}