zoukankan      html  css  js  c++  java
  • hdu4313(生成树)

    最小生成树变形

    将边倒序排列,

    从大的边开始遍历,

    如果查的时候发现两个连通分量都具有危险点,那么该边该删;

    否则将两个连通分量并成一个连通分量。

    照着书上的模板打,因为将i,j定义成了全局变量,所以出现了bug.TLE了多次。

    改正后AC,附AC代码:

    View Code
    #include <iostream>
    #include <string.h>
    #include <stdio.h>
    #include <math.h>
    #include <stdlib.h>
    #include <algorithm>
    using namespace std;
    #define MAXN 100500
    struct edge{
        int u,v,w;
    }edges[MAXN];
    int parent[MAXN];
    int vis[MAXN];
    int n,k;
    long long sumweight;
    void UFset(){
        for(int i=0;i<n;i++){
            parent[i]=-1;
        }
    }
    int Find(int x){
        int s;
        for(s=x;parent[s]>=0;s=parent[s]);
        while(s!=x){
            int tmp=parent[x];
            parent[x]=s;
            x=tmp;
        }
        return s;
    }
    void Union(int R1,int R2){
        int r1=Find(R1),r2=Find(R2);
        int tmp=parent[r1]+parent[r2];
    
        if(vis[r1]==1){
            parent[r2]=r1;
            parent[r1]=tmp;
        }
        else{
            parent[r1]=r2;
            parent[r2]=tmp;
        }
    
    }
    int cmp(const void *a,const void *b){
        edge aa=*(const edge *)a;
        edge bb=*(const edge *)b;
        return bb.w-aa.w;
    }
    void Kruskal(){
        int u,v;
        UFset();
        for(int i=0;i<n-1;i++){
            u=edges[i].u;v=edges[i].v;
            if(vis[Find(u)]==1 && vis[Find(v)]==1){
                sumweight+=edges[i].w;
            }
            else{
                Union(u,v);
            }
        }
    }
    int main(){
        //freopen("in.txt","r",stdin);
        int a,b,c,mac;
        int ncas;
        scanf("%d",&ncas);
        while(ncas--){
            scanf("%d%d",&n,&k);
            for(int i=0;i<n-1;i++){
                scanf("%d%d%d",&a,&b,&c);
                edges[i].u=a;
                edges[i].v=b;
                edges[i].w=c;
            }
            memset(vis,0,sizeof(vis));
            for(int i=0;i<k;i++){
                scanf("%d",&mac);
                vis[mac]=1;
            }
            qsort(edges,n-1,sizeof(edges[0]),cmp);
            sumweight=0;
            Kruskal();
            printf("%I64d\n",sumweight);
        }
        return 0;
    }

    杭电OJ真是奇葩,

    1.C++比G++快;
    2.不支持%lld,输入或输出要用%I64d。定义用long long就成。

    接下来要把所有与生成树有关的算法都学一下,刷一些与生成树有关的题。

    该题还可以用树形DP做,近期要学一下树形DP。

  • 相关阅读:
    自定义镜像流程
    go语言中go+select的理解
    go语言中var声明chan、map、指针,注意的情况
    docker SDK 的基本学习
    ubuntu上安装postgres以及在远程连接上的坑
    go语言模板中的os.Stdout标准输出转化为string
    angular7升级到angular8
    sudo不用在输入密码
    go语言简单的执行shell命令
    Ubuntu上面安装docker
  • 原文地址:https://www.cnblogs.com/markliu/p/2612042.html
Copyright © 2011-2022 走看看