• #3409. 小P的生成树(mst)


    题目描述

    小`P`时勤于思考的好孩子,自从学习了最大生成树后,他就一直想:能否将边权范围从实数推广到复数呢?可是马上小`P`就发现了问题,复数之间的大小关系并没有定义。于是对于任意两个复数 $z_1,z_2$ ,小`P`定义 $z_1<z_2$ 当且仅当 $|z_1|<|z_2|$ 。

    现在,给出一张 $n$ 个点 $m$ 条边的简单无向带权图,小`P`想问你,如果按照他对复数大小的定义,这个图的最大生成树是什么?

    题解

    好像在杭州的时候讲过这题,答案是一个复数,放在复平面上的话是个向量,所以如果确定方向的话我们就是把所有向量在这个平面上做投影,要使得投影的和最大去做最大生成树。

    可惜角度非常多,那我们可以做最大生成树的时候我们只需要确定两条边的大小关系,不需要只要他具体的值。所以我们可以考虑到两条向量相等的时候角度是确定的,所以我们把这些角度记录下来后排序,然后对于两角直接的方向边的大小关系都是一样的,所以任选一个方向去投影,做最大生成树即可。

    效率: $O(m^3logm)$ (有排序)。

    代码

    #include <bits/stdc++.h>
    #define db double
    using namespace std;
    const db p=acos(-1);
    int n,m,t,u[205],v[205],fa[55];
    db a[205],b[205],f[40005],ans;
    struct O{int x,y;db i,j,z;}g[205];
    int get(int x){return x==fa[x]?x:fa[x]=get(fa[x]);}
    bool cmp(O A,O B){return A.z>B.z;}
    db work(db w){
        db X=sin(w),Y=cos(w),U=0,V=0;
        for (int i=1;i<=m;i++)
            g[i]=(O){u[i],v[i],a[i],b[i],b[i]*X+a[i]*Y};
        sort(g+1,g+m+1,cmp);
        for (int i=1;i<=n;i++) fa[i]=i;
        for (int x,y,i=1;i<=m;i++){
            x=get(g[i].x);y=get(g[i].y);
            if (x!=y) fa[x]=y,U+=g[i].i,V+=g[i].j;
        }
        return U*U+V*V;
    }
    int main(){
        cin>>n>>m;
        for (int i=1;i<=m;i++)
            scanf("%d%d%lf%lf",&u[i],&v[i],&a[i],&b[i]);
        for (int i=1;i<m;i++)
            for (int j=i+1;j<=m;j++){
                if (b[i]==b[j]) f[++t]=-p/2;
                else f[++t]=atan((a[i]-a[j])/(b[i]-b[j]));
                f[t+1]=f[t]+p;t++;
            }
        f[++t]=-p/2;f[++t]=p*5/2;
        sort(f+1,f+t+1);t=unique(f+1,f+t+1)-f-1;
        for (int i=1;i<=t;i++)
            ans=max(ans,work((f[i]+f[i-1])/2));
        printf("%.6lf
    ",sqrt(ans));return 0;
    }
  • 相关阅读:
    20201022-1 每周例行报告
    2020高级软件工程“领跑衫”获奖感言
    20201015-3 每周例行报告
    20201008-1 每周例行报告
    竞拍作业
    20201207-总结-作业
    20201126-1每周例行报告
    20201120-1每周例行报告
    20201112 -1每周例行报告
    20201105-1例行报告
  • 原文地址:https://www.cnblogs.com/xjqxjq/p/12392122.html
Copyright © 2020-2023  润新知