题目链接:https://vjudge.net/problem

题意:

给各位看一下题意,算法详解看下面大佬博客吧,写的很好。

参考博客:最小k度限制生成树 - chty - 博客园  https://www.cnblogs.com/chty/p/5934669.html

代码:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
#include<stack>
#include<cmath>
#include<vector>
#include<set>
#include<cstdio>
#include<string>
#include<deque>
using namespace std;
typedef long long LL;
#define eps 1e-8
#define INF 0xffffff
#define maxn 105
map<string,int>mp;
struct node{
    int u,v,w,next;
}edge[maxn*maxn],dp[maxn];
int n,m,k,t,id,cnt;
int sum,md;//边权和,最小的度
int pre[maxn],check[maxn][maxn],dis[maxn][maxn],minn[maxn],temp[maxn];
//集合的祖先,check[i][j]表示在生成树里面i和j是否有边相连,dis[i][j]表示i和j之间的边权
//minn[i]表示以点i为祖先节点的点集里和树根直接相连的最小边权,temp记录这个点的下标
void init(){
    id=;
    sum=md=;
    memset(check,,sizeof(check));
    ;i<maxn;i++){
        ;j<maxn;j++){
            dis[i][j]=INF;
        }
    }
    ;i<maxn;i++)
    pre[i]=i;
}
void read(){
    init();
    cin>>m;
    string u,v;
    int w;
    mp[;
    ;i<=m;i++){
        cin>>u>>v>>w;
        )
        mp[u]=++id;
        )
        mp[v]=++id;
        edge[i].u=mp[u];
        edge[i].v=mp[v];
        edge[i].w=w;
        dis[mp[u]][mp[v]]=dis[mp[v]][mp[u]]=min(dis[mp[u]][mp[v]],w);
    }
    cin>>k;
}
bool cmp(node a,node b){
    return a.w<b.w;
}
int find(int a){
    return pre[a]==a?a:pre[a]=find(pre[a]);
}
void cal_m_tree(){//计算度为m的最小生成树
    sort(edge+,edge++m,cmp);
    ;i<=m;i++){
        int u=edge[i].u;
        int v=edge[i].v;
        int w=edge[i].w;
        ||v==)
        continue;
        int x=find(u);
        int y=find(v);
        if(x!=y){
            pre[x]=y;
            sum+=w;//把边权加上
            check[u][v]=check[v][u]=;//标记链接u,v的边已经走过
        }
    }
    ;i<=id;i++)
    minn[i]=INF;
    ;i<=id;i++){//寻找各个连通块里面和树根直接相连的最小边
        int f=find(i);
        ]!=INF&&minn[f]>dis[i][]){//更新连通快f的值并记录点的下标
            minn[f]=dis[i][];//
            temp[f]=i;
        }
    }
    ;i<=id;i++){
        if(minn[i]!=INF){
            md++;//度增加
            sum+=minn[i];//权值增加
            check[][temp[i]]=check[temp[i]][]=;//标记边
        }
    }
}
void DFS(int u,int fa){//用动态规划来计算从树根到生成树上每一个点的1路径上面的最大边权
//同时记录这条边所连接的两点
    ;i<=id;i++){
        if(i==fa)
        continue;
        ){//动态规划,到点i的最大边权dp[i].w=max{dp[u].w,dis[i][u]}
            ){
                dp[i].w=dis[i][u];
                dp[i].u=u;
                dp[i].v=i;
            }
            else{
                dp[i]=dp[u];
            }
            DFS(i,u);
        }

    }
}
void cal_k_tree(){//计算度为m+1到k的最小生成树,可以直接跳出
    ;i<=k;i++){
        ;j<=id;j++)
        dp[j].w=-INF;
        DFS(,-);
        int ans=INF,u;//ans记录接下来度为i的生成树和之前生成树的权值之差的最小值,如果ans<0,说明还可以
        //使边权变小,否则在度数增加时边权和只会变大,所以可以直接跳出
        ;j<=id;j++){
            ]==&&dis[][j]!=INF){
                ][j]-dp[j].w){
                    ans=dis[][j]-dp[j].w;
                    u=j;
                }
            }
        }
        )//无法增广,直接跳出
        break;
        int a=dp[u].u;
        int b=dp[u].v;
        check[a][b]=check[b][a]=;//去掉一条边
        check[][u]=check[u][]=;//增加一条边
        sum+=ans;//边权减少
    }
}
int main()
{
    read();
    cal_m_tree();
    cal_k_tree();
    printf("Total miles driven: %d\n",sum);
    ;
}

poj 1639 最小k度限制生成树的更多相关文章

  1. 【POJ 1639】 Picnic Planning (最小k度限制生成树)

    [题意] 有n个巨人要去Park聚会.巨人A和先到巨人B那里去,然后和巨人B一起去Park.B君是个土豪,他家的停车场很大,可以停很多车,但是Park的停车场是比较小.只能停k辆车.现在问你在这个限制 ...

  2. 最小k度限制生成树

    [题目描述] 给你一个图,n个点,m条边,求一颗生成树满足如下条件: (1)结点1的度不超过k. (2)在(1)条件下所求生成树最小. [算法引入] 最小k度限制生成树,就是指有特殊的某一点的度不能超 ...

  3. poj1639 Picnic Planning,K度限制生成树

    题意: 矮人虽小却喜欢乘坐巨大的轿车,车大到能够装下不管多少矮人.某天,N(N≤20)个矮人打算到野外聚餐.为了集中到聚餐地点,矮人A 要么开车到矮人B 家中,留下自己的轿车在矮人B 家,然后乘坐B ...

  4. poj 1639 Picnic Planning 度限制mst

    https://vjudge.net/problem/POJ-1639 题意: 有一群人,他们要去某一个地方,每个车可以装无数个人,给出了n条路,包含的信息有路连接的地方,以及路的长度,路是双向的,但 ...

  5. 最小k度最小生成树模板

    代码是抄的 题解是瞄的 可我想学习的心是真的嘤嘤嘤 然而 还是上传一份ioi大神的论文吧 链接:https://pan.baidu.com/s/1neIW9QeZEa0hXsUqJTjmeQ 密码:b ...

  6. Picnic Planning POJ - 1639(最小k度生成树)

    The Contortion Brothers are a famous set of circus clowns, known worldwide for their incredible abil ...

  7. K度限制MST poj 1639

    /* k度限制MST:有一个点的度<=k的MST poj 1639 要求1号点的度不超过k 求MST 我们先把1号点扔掉 跑MST 假设有sum个连通分支 然后把这sum个分支连到1上 就得到了 ...

  8. POJ 1639 Picnic Planning:最小度限制生成树

    题目链接:http://poj.org/problem?id=1639 题意: 给你一个无向图,n个节点,m条边,每条边有边权. 让你求一棵最小生成树,同时保证1号节点的度数<=k. 题解: 最 ...

  9. HDU 4862 Jump(最小K路径覆盖)

    输入一个n×m网格图,每个结点的值为0-9,可以从任意点出发不超过k次,走完每个点且仅访问每个结点一次,问最终的能量最大值.不可全部走完的情况输出-1. 初始能量为0. 而结点(x,y)可以跳跃到结点 ...

随机推荐

  1. 全志A33 linux led驱动编程(附实测参考代码)

    开发平台 * 芯灵思SinlinxA33开发板 淘宝店铺: https://sinlinx.taobao.com/ 嵌入式linux 开发板交流 QQ:641395230 开发平台 * 芯灵思Sinl ...

  2. 20165308 2017-2018-2 《Java程序设计》课程总结

    20165308 2017-2018-2 <Java程序设计>课程总结 一.每周作业及实验报告链接汇总 我期待的师生关系 学习基础和c语言调查 Linux 安装及学习 第一周学习总结 第二 ...

  3. bootstrap 模态框事件

    事件 描述 实例 show.bs.modal 在调用 show 方法后触发. $('#identifier').on('show.bs.modal', function () { // 执行一些动作. ...

  4. Linux eclipse 编译C++

    1.软件安装 2.新建C++工程 3.输入新建文件夹的名字 4.新建main.cpp文件 5.编辑main.cpp #include<iostream> int main(){ std:: ...

  5. Eclipse+PyDev 安装和配置

    Eclipse+PyDev 安装和配置 2012-03-17 23:23:23 | 17465次阅读 | 评论:0 条 |  Python开发有很多工具,其中Eclipse+Pydev 是最常见的一种 ...

  6. 如何从 VSS 迁移到Team Foundation Server

    TFS 2012自带了vss upgrade wizard工具, 在Team Foundation Server管理控制台左侧的最后一个菜单其他工具和组件中,选择Visual SourceSafe升级 ...

  7. 《女神异闻录 5》的 UI 设计

    转自:https://www.zhihu.com/question/50995871?sort=created <女神异闻录5>是近两年最为火热的JRPG游戏之一,它的出色不仅在于剧情暗讽 ...

  8. MOBA英雄AI设计分享

    转自:http://www.gamelook.com.cn/2018/07/333877 文/wataloo 1  设计概要 1.1  设计原则和目的 英雄AI的目的主要有: 1.新手过渡局,让玩家刚 ...

  9. MySQL 之 MHA + ProxySQL + keepalived 实现读写分离,高可用(二)

    ProxySQL安装 yum/rpm安装 在github或官网上可以下载rpm包,wiki的Getting start章节有详细介绍. cat <<EOF | tee /etc/yum.r ...

  10. Quartz入门及简单实现

    Quartz简介 Quartz是一个功能丰富的开源作业调度库,可以集成到几乎任何Java应用程序中 - 从最小的独立应用程序到最大的电子商务系统.Quartz可以用来创建执行数十,数百乃至数万个作业的 ...