zoukankan      html  css  js  c++  java
  • UVALive

    https://vjudge.net/problem/UVALive-5713

    首先明确题意

    ①希望使n个城市联通且道路最短

    ②可以修一条魔法道路不花钱 

    ③设A为魔法道路连接的两座城市的人口之和,B为总花费,希望使得A/B最大


    就是非严格次小生成树

    又被double锤爆了呜呜呜

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    
    #define ri register int
    #define u int
    #define NN 1005
    #define MM 1005*1005
    
    namespace fast {
        inline u in() {
            u x(0);
            char s=getchar();
            while(s<'0'||s>'9') {
                s=getchar();
            }
            while(s>='0'&&s<='9') {
                x=(x<<1)+(x<<3)+s-'0';
                s=getchar();
            }
            return x;
        }
    }
    
    using fast::in;
    using std::queue;
    using std::pair;
    
    namespace cas {
        u fa[NN];
        inline u getfa(u x) {
            u r(x),k;
            while(fa[r]^r) {
                r=fa[r];
            }
            while(x^r) {
                k=x,x=fa[x],fa[k]=r;
            }
            return r;
        }
        inline void pri(const u &n) {
            for(ri i=1; i<=n; ++i)fa[i]=i;
        }
    }
    
    using namespace cas;
    
    namespace all {
        u N,M,T,cnt,h[NN];
        struct node {
            u to,next;
            double va;
        } a[MM];
        inline void add(const u &x,const u &y,const double &z) {
            a[++cnt].next=h[x],a[cnt].to=y,a[cnt].va=z,h[x]=cnt;
        }
    
        struct node1 {
            u x,y,z;
        } b[NN];
        u num,n;
        struct node2 {
            u x,y;
            double z;
        } c[MM];
        double calc(const double &x,const double &y,const double &xx,const double &yy) {
            return std::sqrt((x-xx)*(x-xx)+(y-yy)*(y-yy));
        }
        bool cmp(const node2 &x,const node2 &y) {
            return x.z<y.z;
        }
        double m[NN][NN],g[NN][NN];
    
        double dfs(const u &x,const u &y,const u &prt,double mi) {
            if(g[x][y]) return g[x][y];
            if(x^y) {
                double _re;
                for(ri i(h[x]); i; i=a[i].next) {
                    u _y(a[i].to);
                    if(_y==prt) continue;
                    _re=std::max(mi,a[i].va);
                    double _r=dfs(_y,y,x,_re);
                    if(_r>0) {
                        return _r;
                    }
                }
                return 0;
            } else {
                return mi;
            }
        }
    
        inline void solve() {
            T=in();
            while(T--) {
                n=num=cnt=0;
                std::memset(h,0,sizeof(h));
                std::memset(m,0,sizeof(m));
                std::memset(g,0,sizeof(g));
                N=in();
                for(ri i(1); i<=N; ++i) {
                    u _x(in()),_y(in()),_z(in());
                    b[i].x=_x,b[i].y=_y,b[i].z=_z;//点 坐标,人数
                }
                for(ri i(1); i<=N; ++i) {
                    for(ri j(1); j<=N; ++j) {
                        if(i^j) {
                            c[++num].x=i,c[num].y=j;
                            c[num].z=calc((double)b[i].x,(double)b[i].y,(double)b[j].x,(double)b[j].y);//边 两点,距离
                        }
                    }
                }
                std::sort(c+1,c+num+1,cmp);
                u _cnt(0);
                double ans(0.0);
                pri(N);
                while(n<N-1) {
                    u fx(getfa(c[++_cnt].x)),fy(getfa(c[_cnt].y));
                    if(fx^fy) {
                        fa[fx]=fy,++n,ans+=c[_cnt].z;
                        add(c[_cnt].x,c[_cnt].y,c[_cnt].z);
                        add(c[_cnt].y,c[_cnt].x,c[_cnt].z);
                        m[c[_cnt].x][c[_cnt].y]=m[c[_cnt].y][c[_cnt].x]=c[_cnt].z;
                    }
                }
                double as(0);
                for(ri i(1); i<=N; ++i) {
                    for(ri j(i+1); j<=N; ++j) {
                        double _a(b[i].z+b[j].z),_b(ans);
                        if(m[i][j]) {
                            _b-=m[i][j];
                        } else {
                            _b-=(g[i][j]=g[j][i]=dfs(i,j,0,0));
                        }
                        as=std::max(as,_a/_b);
                        /*if(as>6.324) {
                            u _p(0);
                        }*/
                    }
                }
                printf("%.2lf
    ",as);
            }
        }
    }
    
    int main() {
        //freopen("x.txt","r",stdin);
        all::solve();
    }
  • 相关阅读:
    POJ 1811 Prime Test 素性测试 分解素因子
    sysbench的安装与使用
    电脑中已有VS2005和VS2010安装.NET3.5失败的解决方案
    I.MX6 show battery states in commandLine
    RPi 2B Raspbian system install
    I.MX6 bq27441 driver porting
    I.MX6 隐藏电池图标
    I.MX6 Power off register hacking
    I.MX6 Goodix GT9xx touchscreen driver porting
    busybox filesystem httpd php-5.5.31 sqlite3 webserver
  • 原文地址:https://www.cnblogs.com/ling-zhi/p/11619961.html
Copyright © 2011-2022 走看看