题目链接:https://atcoder.jp/contests/abc143/tasks/abc143_e
题意:
n个城市,m条路。每个路有不同的长度。
现在要你开车从s城到t城。汽车最开始油箱是满的为L升,一升油只能走一单位的路,只能在每个城市加油,不能够在半路上没油。
有q次询问,每次询问从s城走到t城最少加几次油。
题解:
利用floyd求出每个城市之间的最短距离。
如果城市间最短距离小于等于L,则记路径权重为1,表示只需要加一次油就可以到达。
如果最短距离大于L,则标记为无穷,记为无穷大,表示不能够直接到达。
再利用上述方法产生新的路径及权值,跑一遍floyd。即可获得任意两城市之间最少需要加多少次油。
注:无穷大,则视为不可达输出-1,输出最终答案时要减一,因为初始油箱是满的。
AC代码:
#include <bits/stdc++.h>
//#pragma GCC optimize(2)
using namespace std;
#define LL long long
const int maxn=1e6+5;
const int inf = 0x3f3f3f3f;
LL n,m,l,dis[305][305],newdis[305][305];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>m>>l;
for(int i=1;i<305;i++)
{
for(int j=1;j<305;j++)
{
dis[i][j]=newdis[i][j]=inf;
}
dis[i][i]=newdis[i][i]=0;
}
for(int i=0;i<m;i++)
{
int u,v;
LL w;
cin>>u>>v>>w;
newdis[u][v]=dis[u][v]=w;
newdis[v][u]=dis[v][u]=w;
}
for(int k=1;k<=n;k++)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(dis[i][k]!=inf&&dis[k][j]!=inf)
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
}
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
newdis[i][j]=(dis[i][j]<=l?1:inf);
}
newdis[i][i]=0;
}
for(int k=1;k<=n;k++)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(newdis[i][k]!=inf&&newdis[k][j]!=inf)
newdis[i][j]=min(newdis[i][j],newdis[i][k]+newdis[k][j]);
}
}
}
int q;
cin>>q;
int s,t;
while(q--)
{
cin>>s>>t;
if(newdis[s][t]==inf)
{
cout<<"-1\n";
}
else
{
cout<<newdis[s][t]-1<<"\n";
}
}
return 0;
}
欢迎评论!