hdu4081Qin Shi Huang's National Road System

来源:互联网 发布:centos 锁屏 编辑:程序博客网 时间:2024/05/29 11:20

链接:http://acm.hdu.edu.cn/showproblem.php?pid=4081

题意:给定n个点,每个点有点权,求生成树,然后删掉一条边增加一条魔法边使得魔法边连的两个节点的点权和除以剩余边的和最大。

分析:先求最小生成树,枚举删哪条边和删完后两颗子树中的最大点权,魔法边就是连这条个点。

代码:

#include<map>#include<set>#include<cmath>#include<queue>#include<bitset>#include<math.h>#include<vector>#include<string>#include<stdio.h>#include<cstring>#include<iostream>#include<algorithm>#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;const int N=1010;const int mod=100000000;const int MOD1=1000000007;const int MOD2=1000000009;const double EPS=0.00000001;typedef long long ll;const ll MOD=1000000007;const int INF=1000000010;const ll MAX=1ll<<55;const double pi=acos(-1.0);typedef double db;typedef unsigned long long ull;struct node {    int a,b;    db w;    bool operator < (const node x) const {        return w<x.w;    }}f[500010];db w[2*N],fd[N];int x[N],y[N],p[N],fa[N],mx[N],d[N][12];int tot,in[N],out[N],u[N],v[2*N],pre[2*N];void add(int a,int b,db c) {    v[tot]=b;w[tot]=c;pre[tot]=u[a];u[a]=tot++;}db dis(int a,int b) {    return sqrt((x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]));}int find_f(int a) {    return fa[a]==a?a:find_f(fa[a]);}void dfs(int a,int b,db c) {    in[a]=++tot;d[tot][0]=p[a];    mx[a]=p[a];fa[a]=b;fd[a]=c;    for (int i=u[a];i!=-1;i=pre[i])    if (v[i]==b) continue ;    else { dfs(v[i],a,w[i]);mx[a]=max(mx[a],mx[v[i]]); }    out[a]=tot;}void dealrmq(int n) {    int i,j;    for (i=1;i<12;i++)        for (j=1;j<=n;j++)        if (j+(1<<i)-1>n) break ;        else d[j][i]=max(d[j][i-1],d[j+(1<<(i-1))][i-1]);}int get(int l,int r) {    if (l>r) return 0;    int w=(int)log2(r-l+1);    return max(d[l][w],d[r-(1<<w)+1][w]);}int main(){    int i,j,k,n,t,f1,f2;    db sum,ans;    scanf("%d", &t);    while (t--) {        scanf("%d", &n);        for (i=1;i<=n;i++) scanf("%d%d%d", &x[i], &y[i], &p[i]);        for (k=0,i=1;i<=n;i++)            for (j=i+1;j<=n;j++) {                k++;f[k].a=i;f[k].b=j;f[k].w=dis(i,j);            }        for (i=1;i<=n;i++) fa[i]=i;        sort(f+1,f+k+1);        sum=tot=0;        memset(u,-1,sizeof(u));        for (i=1;i<=k;i++) {            f1=find_f(f[i].a);f2=find_f(f[i].b);            if (f1!=f2) {                sum+=f[i].w;fa[f1]=f2;                add(f[i].a,f[i].b,f[i].w);                add(f[i].b,f[i].a,f[i].w);            }        }        ans=tot=0;        dfs(1,0,0);        dealrmq(n);        for (i=2;i<=n;i++) ans=max(ans,1.0*(mx[i]+max(get(1,in[i]-1),get(out[i]+1,n)))/(sum-fd[i]));        printf("%.2f\n", ans);    }    return 0;}


0 0
原创粉丝点击