Atcoder Beginnner Contest 143 E-Travel by Car(floyd算法)

题目链接: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;
}

欢迎评论!

猜你喜欢

转载自blog.csdn.net/wjl_zyl_1314/article/details/102797533