腾讯大战360
思路:
1.floyed不行,时间复杂度太高了,考虑 n 2 n^2 n2或更快的算法。
2.我们可以跑两遍迪杰斯特拉,分别以S与T为起点,最后一个循环找到总时间最短的节点。
CODE:
#include<iostream>
#include<algorithm>
#include<cstring>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
inline ll min1(ll x,ll y){
return x < y ? x : y;
}
inline ll max1(ll x,ll y)
{
return x > y ? x : y;
}
ll n,m,s,t,a[5010][5010],ans = INF;
ll d1[5010],d2[5010];
bool b[5010];
int main()
{
ios::sync_with_stdio(false);
cin >> n >> m;
memset(a,0x3f,sizeof(a));
memset(d1,0x3f,sizeof(d1));
memset(d2,0x3f,sizeof(d2));
for(int i = 1;i <= n;++i) a[i][i] = 0;
for(ll i = 1,x,y,v;i <= m;++i)
{
cin >> x >> y >> v;
a[x][y] = a[y][x] = v;
}
cin >> s >> t;
d1[s] = 0;
for(int i = 1;i <= n - 1;++i)
{
ll x = 0;
for(int j = 1;j <= n;++j)
{
if(!b[j]&&(!x || d1[j] < d1[x])) x = j;
}
b[x] = true;
for(int j = 1;j <= n;++j)
{
d1[j] = min1(d1[j],d1[x] + a[x][j]);
}
}
memset(b,false,sizeof(b));
d2[t] = 0;
for(ll i = 1;i <= n - 1;++i)
{
ll x = 0;
for(ll j = 1;j <= n;++j)
{
if(!b[j]&&(!x || d2[j] < d2[x])) x = j;
}
b[x] = true;
for(ll j = 1;j <= n;++j)
{
d2[j] = min1(d2[j],d2[x] + a[x][j]);
}
}
//cout << d1[t] << " " << d2[s] << endl;
for(ll i = 1,t;i <= n;++i)
{
ans = min1(ans,max1(d1[i],d2[i]));//这里不能写错
}
if(ans >= INF)
{
puts("Peace!");
}
else
{
cout << ans << endl;
}
return 0;
}
还是有点危险。