住在南山校区的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;
}