7-12 坚持散步(PTA)

住在南山校区的HY喜欢散步。他发现南山校区有n个景点(从1到n进行编号)很值得观赏,比如竹林舞步,小河夕阳等。这些景点中,有些相互能够直达,而有些要先经过其他的一些景点才能到达。他已经记下了一些直达道路的用时信息。散步是好的,但散步太久也会累的,所以当他身处某个景点时,就想知道从这个景点散步到另一个他想去的景点的最少用时。

输入格式:

首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。
每组测试包含两个部分。分别是: 景点信息 和 查询。

景点信息 部分,首先是2个整数n和m(2≤n≤100,1≤m≤n(n-1)/2),分别表示有n个景点,以及m条直达道路的用时信息。然后有m行输入,每行输入三个整数a,b,c(1≤a,b≤n,a≠b,1≤c<100),表示由景点a散步到景点b,HY散步需要用时c分钟,当然,他由景点b散步到景点a也要c分钟。

查询 部分,首先是1个整数k(1<=k<=5000),表示后面接k次询问。紧接着k行数据,每行包括两个整数s,d(1≤s,d≤n,s≠d),分别表示HY想知道从景点s散步到另一个景点d的用时(分钟数)。

注意,因为HY有点粗心,可能发生以下情况:
(1)他所记下有些用时信息可能重复,比如:
1 2 3
2 1 3
(2)有些同一条路的用时信息可能不一致,比如:
1 2 3
1 2 4
在这种情况下,以其中用时最少的信息为准。
(3)有些路用时信息可能忘记了,比如有3个景点1,2,3;他只记住1条路的用时:
1 2 1
在这种情况下,认为从景点1到景点3没有直达的路,从景点2到景点3也没有直达的路。

输出格式:

对于每组测试,每次询问输出一行,包含一个整数,表示从景点s散步到另一个景点d的最少用时。如果景点s到景点d无路可通,输出-1。

输入样例:

2
3 2
1 2 3
2 3 1
3
1 2
1 3
3 2
3 2
1 2 3
2 1 2
3
1 2
1 3
2 3

输出样例:

3
4
1
2
-1
-1

提示:

输入数据较多,建议用scanf函数输入

思路:

最短路,弗洛伊德

用dijkstra会超时

代码: 

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
const int N=110,M=100010;
typedef pair<int,int> pii;
int n,m;
int h[N],e[M],ne[M],w[M],idx;
int d[N][N];
bool st[N];
signed main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int t;
    cin>>t;
    while(t--)
    {
        memset(h,-1,sizeof h);
        memset(d,0x3f,sizeof d);
        cin>>n>>m;
        while(m--)
        {
            int a,b,c;
            cin>>a>>b>>c;
            if(c<d[a][b])
            {
                d[a][b]=c,d[b][a]=c;
            }
        }
        //floyd
        for(int k=1;k<=n;k++)
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
        int k,s,r;
        cin>>k;
        while(k--)
        {
            cin>>s>>r;
            if(d[s][r]==0x3f3f3f3f3f3f3f3f) cout<<"-1"<<endl;
            else cout<<d[s][r]<<endl;
        }
    }
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值