hdu 4081 Qin Shi Huang's National Road System (次小生成树 - 模板)

链接:http://acm.hdu.edu.cn/showproblem.php?pid=4081
来源:2011 Asia Beijing Regional Contest

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;

const int inf=0x3f3f3f3f;
typedef long long ll;
const int Max_n=1e3+10;
double cost[Max_n][Max_n],dis[Max_n];
double path[Max_n][Max_n],ans;
bool used[Max_n][Max_n],vis[Max_n];
int pre[Max_n],n;

struct Node{
    int x,y,peo;
}node[Max_n];

double cal(int i,int j){
    return sqrt((node[i].x-node[j].x)*(node[i].x-node[j].x)+(node[i].y-node[j].y)*(node[i].y-node[j].y));
}

double Prim(){
    double ans=0;
    vis[1]=true;
    for(int i=1;i<=n;i++){
        dis[i]=cost[1][i];
        pre[i]=1;
    }
    for(int i=2;i<=n;i++){
        double minc=inf; int p=-1;
        for(int j=1;j<=n;j++){
            if(!vis[j]&&dis[j]<minc){
                minc=dis[j];
                p=j;
            }
        }
        if(minc==inf) return -1;
        ans+=minc;
        vis[p]=true;
        used[p][pre[p]]=used[pre[p]][p]=true;
        for(int j=1;j<=n;j++){
            if(vis[j]&&j!=p){
                path[j][p]=path[p][j]=max(path[j][pre[p]],dis[p]);
                //要么是新添加的边,要么是原来最长的
            }
            if(!vis[j]&&dis[j]>cost[j][p]){
                dis[j]=cost[p][j];
                pre[j]=p;
            }
        }
    }
    return ans;
}

int main(){
    int T; scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d%d%d",&node[i].x,&node[i].y,&node[i].peo);
        for(int i=1;i<=n;i++){
            vis[i]=false; dis[i]=inf;
            for(int j=1;j<=n;j++){
                used[i][j]=false;
                path[i][j]=0;
            }
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++)
                cost[i][j]=cal(i,j);
        }
        //for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) printf("%.2f%c",cost[i][j],j==n?'\n':' ');
        double res=Prim();
        double ans=0;//先求出最小生成树,遍历边,找次小生成树或者直接删除边
        //cout<<"         "<<ans<<endl;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(i==j) continue;
                if(used[i][j]) ans=max(ans,(node[i].peo+node[j].peo)/(res-cost[i][j]));
                else ans=max(ans,(node[i].peo+node[j].peo)/(res-path[i][j]));
            }
        }
        printf("%.2f\n",ans);
    }
    return 0;
}
发布了166 篇原创文章 · 获赞 68 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_42217376/article/details/102720693