LA 5713 秦始皇修路(最小生成树 + 简单处理)

思路: 我们只需要n方 处理出u到v的最小生成树上的最大路径  记录在cost 数组中。

代码: 

#include<bits/stdc++.h>

using namespace std;
typedef pair<int ,int > pii;
const int N=1e3+5;
const int M=1e6+5;

double cost[N][N];

struct node
{
    double w;
    int u,v;
}edges[M];

bool cmp(node a,node b)
{
    return a.w<b.w;
}

int tx[N],ty[N];
int peo[N];
int f[N];
int n;

double get_dis(int i,int j)
{
    int ax,bx,ay,by;
    ax=tx[i]; bx=tx[j];
    ay=ty[i]; by=ty[j];
    ax=abs(ax-bx);  ay=abs(ay-by);
    return sqrt(ax*ax+ay*ay);
}

int getf(int x)
{
    return f[x]==x?x:(f[x]=getf(f[x]));
}

int merge(int x,int y)
{
    int t1=getf(x);
    int t2=getf(y);
    if(t1!=t2){
        f[t2]=t1;
        return 1;
    }
    return 0;
}

int head[N];
int totc;
int vis[N];

struct node1
{
    int to;
    double w;
    int next;
}Edge[2*N+5];

void add(int u,int v,double w)
{
    Edge[++totc].to=v; Edge[totc].w=w; Edge[totc].next=head[u]; head[u]=totc;
}

int Fa;

void dfs(int u,int fa,double maxx)
{
    cost[Fa][u]=maxx;
    for(int i=head[u];i!=-1;i=Edge[i].next)
    {
        int v=Edge[i].to;
        double w=Edge[i].w;
        if(v==fa) continue;
        dfs(v,u,max(maxx,w));
    }
    return ;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d %d %d",&tx[i],&ty[i],&peo[i]);
        }

        int tot=0;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(i==j) continue;
                edges[++tot].u=i; edges[tot].v=j; edges[tot].w=get_dis(i,j);
            }
        }

        totc=0;
        memset(head,-1,sizeof(head));

        sort(edges+1,edges+tot+1,cmp);
        int cnt=1;
        for(int i=0;i<=n;i++) f[i]=i;
        int u,v;
        double sum=0;
        for(int i=1;i<=tot;i++){
            u=edges[i].u;  v=edges[i].v;
            if(merge(u,v)){
                sum+=edges[i].w;
                cnt++;
                add(u,v,edges[i].w);
                add(v,u,edges[i].w);
                if(cnt==n) break;
            }
        }

        //cout<<"sum "<<sum<<endl;

        for(int i=1;i<=n;i++){
            Fa=i;
            dfs(i,-1,0);
        }

        double A,B;
        double ans=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++){
                if(i==j) continue;
                A=(peo[i]+peo[j])*1.0;
                B=sum-cost[i][j];
                //if(B==0) continue;
                ans=max(ans,A/B);
            }
        }


        printf("%.2f\n",ans);

    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/yjt9299/article/details/81048035
LA
今日推荐