题意:求图的最小生成树,不过其中一个点在最小生成树中的度要小于等于k。

分析:先将其它点形成森林,每棵树都是最小生成树。然后从那个点(不妨设是0号结点)连条边到最小生成树中。这样一来整体就形成了一棵树,但不一定是最小生成树。

现在构造最小生成树有个贪心的方法,具体证明见黑书302页。不妨设,现在0号结点还剩度m,那么我们如果加一条0至其它一点的边,必定会存在环,此时肯定要去掉一条环上最大的一条边,至于连接0和哪个结点的边,就要枚举了,判断连哪个结点总权值减小的最大,如此进行m次即可。不过,枚举+找最长的边,时间复杂度为O(n^2)了,最多k次,总的是O(k*n^2)。优化是每次加入0至某个点的一条边时都更新从这条边能到达的其它点的路径的最大值。然后枚举时只要直接判断就行,找到加的那点后,加边时再更新其能到的点的最大值。这两个操作是并行的,时间复杂度为O(n),成功的将时间复杂度降为O(k*n)

#include<stdio.h>
#include<iostream>
using namespace std;
const int maxint=0x3fffffff;
struct point
{
int u,v,maxw;
}p[110];
char s[110][110];
int mind,sum,kk,num,g[110][110],d[110],pre[110];
bool flag[110],link[110][110];
void Prim(int t)//与t在一个连通分量的点建最小生成树
{
flag[t]=true;
int i,j;
memset(pre,-1,sizeof(pre));
for(i=1;i<num;i++)
{
pre[i]=t;
d[i]=g[t][i];
}
while(1)
{
for(mind=maxint,j=-1,i=1;i<num;i++)
if(!flag[i]&&d[i]!=-1&&d[i]<mind)
{
mind=d[i];
j=i;
}
if(j==-1) break;
flag[j]=true;
if(g[0][j]!=-1&&(g[0][kk]==-1||g[0][kk]>g[0][j]))
kk=j;//找与0最近的点
link[pre[j]][j]=link[j][pre[j]]=true;
sum+=d[j];//加上总的生成树的权值
for(i=1;i<num;i++)
if(!flag[i]&&g[i][j]!=-1&&(d[i]==-1||d[i]>g[j][i]))
{
pre[i]=j;
d[i]=g[j][i];
}
}
}
void DFS(int t,int pt,int u,int v)
{
int i;
for(i=1;i<num;i++)
if(pt!=i&&link[t][i])
{
if(pt==-1||g[t][i]>=g[u][v])//(t,i)比(u,v)大
{
p[i].maxw=g[t][i];
p[i].u=t;
p[i].v=i;
DFS(i,t,t,i);
}
else
{
p[i].maxw=g[u][v];
p[i].u=u;
p[i].v=v;
DFS(i,t,u,v);
}
}
}
int main()
{
int n,i,j,k,w,ii,jj;
char s1[110],s2[110];
while(scanf("%d",&n)!=EOF)
{
num=1;
strcpy(s[0],"Park");//公园为0
memset(g,-1,sizeof(g));
for(i=1;i<=n;i++)//根据输入构图
{
scanf("%s%s%d",s1,s2,&w);
for(j=0;j<num;j++)
if(strcmp(s[j],s1)==0)
break;
ii=j;
if(ii==num) strcpy(s[num++],s1);
for(j=0;j<num;j++)
if(strcmp(s[j],s2)==0)
break;
jj=j;
if(jj==num) strcpy(s[num++],s2);
if(g[ii][jj]==-1||w<g[ii][jj])
g[ii][jj]=g[jj][ii]=w;
}
scanf("%d",&k);
memset(flag,false,sizeof(flag));
memset(link,false,sizeof(link));
sum=0;
for(i=1;i<num;i++)//将除0之外的建最小生成树并记录最长的一条边,并且每个连通分量加一条与0相连的边
if(!flag[i])
{
k--;
kk=i;
Prim(i);
sum+=g[0][kk];
link[0][kk]=link[kk][0]=true;
DFS(kk,-1,-1,-1);//加入(0,kk)一条边,更新每个点到0的路径中最长的边
}
while(k)
{
k--;
for(j=0,i=1;i<num;i++)//枚举连的点
{
if(link[0][i]||g[0][i]==-1) continue;//与0不连接,或者前面已经连接了
if(j<p[i].maxw-g[0][i])//找最长的边
{
ii=i;
j=p[i].maxw-g[0][i];
}
}
if(j==0) continue;
sum-=j;//边权和减小
link[p[ii].u][p[ii].v]=link[p[ii].v][p[ii].u]=false;//不连接了
link[0][ii]=link[ii][0]=true;//连接
DFS(ii,0,-1,-1);//更新最长的边
}
printf("Total miles driven: %d\n",sum);
}
return 0;
}

pku1639最小度限制生成树相关推荐

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

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

  2. 次小生成树 最小度限制生成树

    首先说明这是一个坑! 因为发现啊次小生成树为什不用树链剖分写(虽然麻烦但是思路各种清晰!),最小度限制生成树可以用lct写(而且是似乎要比那个直接写的算法容易因为要各种建边删边dfs(就没有考虑过时间 ...

  3. 洛谷P5633 最小度限制生成树 题解

    洛谷P5633 最小度限制生成树 题解 题目链接:P5633 最小度限制生成树 题意: 给你一个有 n n n 个节点, m m m 条边的带权无向图,你需要求得一个生成树,使边权总和最小,且满足编号 ...

  4. 【题解】poj1639[2018.8.24校赛 最小生成树 A]Picnic Planning 最小度限制生成树

    题目链接 Description The Contortion Brothers are a famous set of circus clowns, known worldwide for thei ...

  5. pku 1639 Picnic Planning 最小度限制生成树

    http://poj.org/problem?id=1639 题意: 见黑书. 思路: 最小限制树模板题: #include <iostream> #include <cstdio& ...

  6. 野餐规划(最小度限制生成树)

    题目 题目描述 一群小丑演员,以其出色的柔术表演,可以无限量的钻进同一辆汽车中,而闻名世界. 现在他们想要去公园玩耍,但是他们的经费非常紧缺. 他们将乘车前往公园,为了减少花费,他们决定选择一种合理的 ...

  7. ACM 全部算法总结

    ACM 所有算法 附带我学过的算法的博客链接 数据结构 栈 队列 链表 哈希表 哈希数组 堆 优先队列 双端队列 可并堆 左偏堆 二叉查找树 Treap 伸展树 并查集 集合计数问题 二分图的识别 平 ...

  8. POJ 图算法(3)

    图算法 度限制最小生成树和第K最短路,分数规划 poj1639, poj3621, poj2976 poj2449,poj3255,poj2513 最短路,最小生成树,二分图,最大流问题的相关理论 p ...

  9. (转)刘汝佳书上出现的一些题目

    推荐一些题目,希望对参与ICPC竞赛的同学有所帮助. POJ上一些题目在 http://162.105.81.202/course/problemSolving/   可以找到解题报告.        ...

最新文章

  1. python打印列表元素_python打印列表中指定元素的所有下标
  2. 谢文睿:西瓜书 + 南瓜书 吃瓜系列 8. 软间隔与支持向量回归
  3. SecondarySort 原理
  4. Pwn环境配置(二)——VMware虚拟机安装Ubuntu 16.04系统
  5. 【大话数据结构算法】快速排序算法
  6. 认识学习网络布线与数制转换
  7. ajax提交输入内容,当输入用于提交时,AJAX表单提交
  8. 鼠标移动到版块图标产生的渐变效果
  9. Python快速构建神经网络
  10. 全美首个AI本科专业今秋开课,CMU每年最多招35名新生
  11. 普通Java类获取Spring的bean
  12. 主成分分析(PCA)实现代码
  13. Python - matplotlib 不显示中文 findfont: Font family [‘SimHei‘] not found - IOS
  14. 通过温度和湿度计算露点函数
  15. 【Python数据处理篇——DataFrame数据准备】DataFrame的创建、增删改查、数据导入等
  16. 网速dns怎么调快_手机dns怎么设置网速快
  17. 上海房产税免征--积分或居住证
  18. 最新版Jenkins 2.249.3的安装
  19. 支持HEVC/H265 RTMP接收的FFMPEG/FFPLAY WINDOWS版本
  20. Vue-cli3项目seo优化--静态化打包(动态改变页面Titl、keyWords、description)

热门文章

  1. 大数据背景下知识产权侵权行为网络异化与解决思路 —— 以著作权间接侵权为视角...
  2. iOS开发-svga的使用
  3. 18年高新计算机考证初级查询
  4. 上传网页至阿里云服务器步骤
  5. $.extend()用法
  6. 阿里云--云开发平台的创建与部署
  7. java webshell_网站漏洞测试 关于webshell木马后门检测
  8. 力扣第三题 无重复字符的最长子串
  9. JavaScript—jQuery
  10. 第十四周 OJ平台-国家排序