写在前面的话:以后定义走过的一整条路径为路;每两点间的直连路为径,不再重复说明。
思路:
- 正权,无向图,单源点。
- 唯一的不同:路的总长是途径所有小径的长度的最大值,而非加和。
- 明白了这一点,本题就没有难度了。dijkstra。
- 补充:
- double类型一定不要用memset,置什么都不能用。被坑的很惨。
- 可以最后在对距离开方,应该会优化一些,但是本来就是0ms,就不必改了。
代码:
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <queue>
#include <cstring>
#define INF 1500
using namespace std;
const int maxn = 205;
double mp[maxn][maxn];
struct node{
int x,y;
}N[maxn];
int num;
struct stone{
int id;
int dis;
stone(int id,int dis) : id(id) , dis(dis) {} ;
friend bool operator > (stone a,stone b)
{
return a.dis > b.dis;
}
};
priority_queue<stone , vector<stone> , greater<stone> > Q;
bool vis[maxn];
double dis[maxn];
double ans;
void INIT(){
for(int i=1;i<=num;i++)
dis[i] = INF , mp[i][i] = 0;
while(Q.size())
Q.pop();
memset(vis,0,sizeof(vis));
return ;
}
double CAL(int i,int j){
return sqrt( (N[i].x - N[j].x)*(N[i].x - N[j].x) + (N[i].y - N[j].y)*(N[i].y - N[j].y) ) ;
}
void IJK(){
Q.push(stone(1,0)) , dis[1] = 0;
while(Q.size()){
stone cur = Q.top() ; Q.pop();
if(vis[cur.id])
continue;
vis[cur.id] = true;
if(cur.id == 2){
ans = dis[2];
return ;
}
for(int i=1;i<=num;i++){
if(vis[i])
continue;
if(dis[i] > max(mp[cur.id][i] , dis[cur.id])){
dis[i] = max(mp[cur.id][i] , dis[cur.id]);
Q.push(stone(i , dis[i]));
}
}
}
}
int main(){
int T=0;
while(cin>>num && num && ++T){
INIT();
for(int i=1;i<=num;i++)
cin>>N[i].x>>N[i].y;
for(int i=1;i<=num;i++){
for(int j=i+1;j<=num;j++){
mp[i][j] = mp[j][i] = CAL(i,j);
}
}
IJK();
cout<<"Scenario #"<<T<<endl;
cout<<"Frog Distance = "<<fixed<<setprecision(3)<<ans<<endl;
cout<<endl;
}
return 0;
}