4240. 青蛙

在二维平面上有 n 个石头。

第一个石头上有一个青蛙,第二个石头上也有一个青蛙。

第一个石头上的青蛙要到第二个石头上找另一个青蛙玩耍。

它可以直接跳到第二个石头上,也可以经过一系列中间石头,然后再跳到第二个石头上。

这只青蛙希望,它的跳跃过程中,单次跳跃的最长距离尽可能短。

请你计算并输出这个最长距离的最小可能值。

输入格式
输入包含多组测试数据。

每组数据第一行包含一个整数 n。

接下来 n 行,第 i 行包含两个整数 xi,yi,表示第 i 个石头的位置坐标。

每组数据输入完毕后,还会输入一个空行。

当输入 n=0 时,表示输入结束。

输出格式
每组数据先输出一行 Scenario #x,其中 x 是组别编号(从 1 开始)。

然后输出一行 Frog Distance = y,其中 y 是单次跳跃的最长距离的最小可能值,保留三位小数。

每组数据输出完毕后,还要输出一行空行(最后一组数据也不例外)。

数据范围
2≤n≤200,
0≤xi,yi≤1000。

输入样例:
2
0 0
3 4

3
17 4
19 4
18 5

0
输出样例:
Scenario #1
Frog Distance = 5.000

Scenario #2
Frog Distance = 1.414

邻接表正确版

#include<iostream>
#include<cstring>
#include<queue>
#include<cmath>
#include<vector>
using namespace std;
#define INF 0x3f3f3f3f
const int N = 210,M=N*N;
typedef pair<int,int>pii;
int dist[N];
double ans;
int e[M],idx,n,w[M],h[M],ne[M],cnt;
bool st[N];
struct point{
    int x,y;
}p[N];
inline void add(int a,int b,double c){
    e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}
inline int get(int a,int b){
    return (p[a].x-p[b].x)*(p[a].x-p[b].x)+(p[a].y-p[b].y)*(p[a].y-p[b].y);
}
inline double max(double a,double b){return a>b?a:b;}
inline void solve_(){
    idx=0,ans=1e9;
    memset(h,-1,sizeof h);
    memset(dist,0x3f,sizeof dist);
    memset(st,0,sizeof st);
    dist[1]=0;
    for(register int i=1;i<=n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        p[i]={x,y};
    }
    for(register int i(1);i<=n;i++)
    {
        for(register int j(1);j<=n;j++){
            if(i!=j){
                int u=get(i,j);
                add(i,j,u);
            }
        }
    }
    priority_queue<pii,vector<pii>,greater<pii>>q;
    q.push({0,1});
    while(q.size())
    {
        auto it=q.top();
        q.pop();
        int a=it.first,b=it.second;
        if(st[b])continue;
        st[b]=1;
        for(register int i(h[b]);i!=-1;i=ne[i]){
            register int j(e[i]);
            if(dist[j]>max(dist[b],w[i])){
                dist[j]=max(dist[b],w[i]);
             if(!st[j])   q.push({dist[j],j});
            }
        }
    }
    printf("Scenario #%d\nFrog Distance = %.3lf\n\n",++cnt,sqrt(dist[2]));
}
int main(){
    while(~scanf("%d",&n),n){
        solve_();
    }
}

邻接矩阵正确版

#include<iostream>
#include<cstring>
#include<queue>
#include<cmath>
#include<vector>
using namespace std;
#define INF 0x3f3f3f3f
const int N = 210,M=N*N;
typedef pair<int,int>pii;
int dist[N],g[N][N],cnt,n;
bool st[N];
struct point{
    int x,y;
}p[N];

inline int get(int a,int b){
    return (p[a].x-p[b].x)*(p[a].x-p[b].x)+(p[a].y-p[b].y)*(p[a].y-p[b].y);
}
inline double max(double a,double b){return a>b?a:b;}
inline void solve_(){
    memset(g,0x3f,sizeof g);
    memset(dist,0x3f,sizeof dist);
    memset(st,0,sizeof st);
    dist[1]=0;
    for(register int i=1;i<=n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        p[i]={x,y};
    }
    for(register int i(1);i<=n;i++)
    {
        for(register int j(1);j<=n;j++){
            if(i!=j&&g[i][j]==INF){
                g[j][i]=g[i][j]=get(i,j);
            }
        }
    }
    priority_queue<pii,vector<pii>,greater<pii>>q;
    q.push({0,1});
    while(q.size())
    {
        auto it=q.top();
        q.pop();
        int a=it.first,b=it.second;
        if(st[b])continue;
        st[b]=1;
        for(register int i(1);i<=n;i++){
            if(dist[i]>max(dist[b],g[b][i])){
                dist[i]=max(dist[b],g[b][i]);
             if(!st[i])   q.push({dist[i],i});
            }
        }
    }
    printf("Scenario #%d\nFrog Distance = %.3lf\n\n",++cnt,sqrt(dist[2]));
}
int main(){
    while(~scanf("%d",&n),n){
        solve_();
    }
}


错误版,题看成求最短路的最长距离的最小值了,把dist[j]=max(dist[j],dist[t]+w)改成dist[j]=max(dist[t],w)就能记录下最长边,即dist[t]表示1出发到t最长边的最小值

#include<iostream>
#include<cstring>
#include<queue>
#include<cmath>
#include<vector>
using namespace std;
#define INF 0x3f3f3f3f
const int N = 210,M=N*N;
typedef pair<int,int>pii;
vector<pii>lj[N],temp;
int dist[N];
double ans;
int e[M],idx,n,w[M],h[M],ne[M],cnt;
bool st[N];
struct point{
    int x,y;
}p[N];
inline void add(int a,int b,int c){
    e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}
inline int get(int a,int b){
    return (p[a].x-p[b].x)*(p[a].x-p[b].x)+(p[a].y-p[b].y)*(p[a].y-p[b].y);
}
inline double max(double x,int b){
    return x>b?x:b;
}
void dfs(int a,int b){
    temp.push_back({a,b});
  //  cout<<a<<endl;
    if(a==1){
        double res(0);
        for(int i(0);i<temp.size();i++){
            // ans=max(ans,temp[i].second);
            // cout<<temp[i].first<<" "<<temp[i].second<<endl;
         if(temp[i].first!=2)   res=max(res,temp[i].second);
        }
        if(ans>res)ans=res;
        temp.pop_back();
        return ;
    }
    for(int i(0);i<lj[a].size();i++)
    dfs(lj[a][i].first,lj[a][i].second);
    temp.pop_back();
}
void solve_(){
    idx=0,ans=1e9;
    memset(h,-1,sizeof h);
    memset(dist,0x3f,sizeof dist);
    memset(st,0,sizeof st);
    for(int i(0);i<N;i++)lj[i].clear();
    temp.clear();
    dist[1]=0;
    for(int i=1;i<=n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        p[i]={x,y};
    }
    for(int i(1);i<=n;i++)
    {
        for(int j(1);j<=n;j++){
            if(i!=j){
                int u=get(i,j);
                add(i,j,u);
                // cout<<i<<" "<<j<<" "<<u<<endl;
            }
        }
    }
    priority_queue<pii,vector<pii>,greater<pii>>q;
    q.push({0,1});
    while(q.size())
    {
        auto it=q.top();
        q.pop();
        int a=it.first,b=it.second;
        if(st[b])continue;
        st[b]=1;
        for(int i(h[b]);i!=-1;i=ne[i]){
            int j(e[i]);
      //      cout<<dist[j]<<" "<<dist[b]<<" "<<w[i]<<endl;
            if(dist[j]>dist[b]+w[i]){
                lj[j].clear();
                lj[j].push_back({b,w[i]});
                dist[j]=dist[b]+w[i];
             if(!st[j])   q.push({dist[j],j});
            }else if(dist[j]==dist[b]+w[i])lj[j].push_back({b,w[i]});
        }
    }
    dfs(2,0);
    printf("Scenario #%d\nFrog Distance = %.3lf\n\n",++cnt,min(sqrt(ans),sqrt(1.0*dist[2])));
}
int main(){
    while(~scanf("%d",&n),n){
        solve_();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值