zoukankan      html  css  js  c++  java
  • tyvj1391走廊泼水节——kruskal

    题目:http://www.joyoi.cn/problem/tyvj-1391

    大意就是把一个树扩充成一个完全图,并且图中最小生成树仍是原来的树。

    思路很巧妙,把边按权值从小到大排序,然后模拟加边的过程,并查集记录左右两边连通块的大小;

    这样每新加一条边合并两个并查集(完全图),可知此时两边的图中每个点互相连边的最优选择就是连接这两个图的那条边的边权+1;

    这样求最小生成树时要连接这两个连通块,则一定会选择原树边。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int const MAXN=6005;
    int t,n,ct,fa[MAXN],s[MAXN],ans;
    struct N{
        int to,hd,w;
        N(int t=0,int h=0,int w=0):to(t),hd(h),w(w) {}
    }edge[MAXN<<1];
    int find(int x)
    {
        if(fa[x]==x)return x;
        return fa[x]=find(fa[x]);
    }
    bool cmp(N x,N y)
    {
        return x.w<y.w;
    }
    int main()
    {
        scanf("%d",&t);
        while(t--)
        {
            ct=0;ans=0;
            scanf("%d",&n);
            int x,y,z;
            for(int i=1;i<n;i++)
            {
                scanf("%d%d%d",&x,&y,&z);
                edge[++ct]=N(x,y,z);
                fa[i]=i;s[i]=1;
            }
            fa[n]=n;s[n]=1;//!!!
            sort(edge+1,edge+ct+1,cmp);
            for(int i=1;i<n;i++)
            {
                int u=find(edge[i].to);
                int v=find(edge[i].hd);
                if(u!=v)
                {
                    fa[u]=v;
                    ans+=(s[u]*s[v]-1)*(edge[i].w+1);
                    s[v]+=s[u];
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    Laravel 5.2 使用 JWT 完成多用户认证 | Laravel China 社区
    (上线时清缓存)laravel 5.1 的程序性能优化(配置文件)
    linux计划任务及压缩归档
    用户及用户管理
    vim编辑器
    linux进阶命令
    权限管理
    linux基础命令2
    linu基础命令1
    连接Xshell
  • 原文地址:https://www.cnblogs.com/Zinn/p/8859002.html
Copyright © 2011-2022 走看看