hdu4081Qin Shi Huang's National Road System(次小生成树)

来源:互联网 发布:淘宝网高跟鞋 编辑:程序博客网 时间:2024/06/06 10:17

题解:这题就是次小生成树的变形,先求出该最小生成树,然后如果这个点要和前面那个点连接的话,要把之前连接好的最大一条路给断了造成两个连通图,最后答案变成(a[i].num+a[j].num)/(b-Max[i][j])然后取其中的最大值即可。

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>using namespace std;const int mx = 1e3+5;struct node{    int x,y,num;}a[mx];double Max[mx][mx];double dis[mx];int pre[mx],vis[mx];int n;double dist(node a,node b){    return sqrt(pow(1.0*a.x-b.x,2)+pow(1.0*a.y-b.y,2));}double prim(){    memset(vis,0,sizeof(vis));    for(int i = 1; i <= n; i++)        dis[i] = 1e10;    dis[1] = 0;    double ans = 0;    for(int i = 1; i <= n; i++){        int minn = 1e10,x;        for(int j = 1; j <= n; j++)            if(!vis[j]&&dis[j]<minn)                minn = dis[x = j];        vis[x] = 1;        ans += dis[x];        for(int j = 1; j <= n; j++){            if(vis[j]) Max[x][j] = Max[j][x] = x==j?0:max(Max[pre[x]][j],dis[x]);            else if(dis[j]>dist(a[j],a[x]))                dis[j] = dist(a[j],a[x]),pre[j] = x;        }    }    return ans;}double check(double b){    double ans = 0;    for(int i = 1; i <= n; i++)        for(int j = i+1; j <= n; j++)                ans = max(ans,(a[i].num+a[j].num)/(b-Max[i][j]));    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",&a[i].x,&a[i].y,&a[i].num);        memset(Max,0,sizeof(Max));        printf("%.2f\n",check(prim()));    }    return 0;}


阅读全文
0 0
原创粉丝点击