The Contortion Brothers are a famous set of circus clowns, known worldwide for their incredible ability to cram an unlimited number of themselves into even the smallest vehicle. During the off-season, the brothers like to get together for an Annual Contortionists Meeting at a local park. However, the brothers are not only tight with regard to cramped quarters, but with money as well, so they try to find the way to get everyone to the party which minimizes the number of miles put on everyone's cars (thus saving gas, wear and tear, etc.). To this end they are willing to cram themselves into as few cars as necessary to minimize the total number of miles put on all their cars together. This often results in many brothers driving to one brother's house, leaving all but one car there and piling into the remaining one. There is a constraint at the park, however: the parking lot at the picnic site can only hold a limited number of cars, so that must be factored into the overall miserly calculation. Also, due to an entrance fee to the park, once any brother's car arrives at the park it is there to stay; he will not drop off his passengers and then leave to pick up other brothers. Now for your average circus clan, solving this problem is a challenge, so it is left to you to write a program to solve their milage minimization problem.

Input

Input will consist of one problem instance. The first line will contain a single integer n indicating the number of highway connections between brothers or between brothers and the park. The next n lines will contain one connection per line, of the form name1 name2 dist, where name1 and name2 are either the names of two brothers or the word Park and a brother's name (in either order), and dist is the integer distance between them. These roads will all be 2-way roads, and dist will always be positive.The maximum number of brothers will be 20 and the maximumlength of any name will be 10 characters.Following these n lines will be one final line containing an integer s which specifies the number of cars which can fit in the parking lot of the picnic site. You may assume that there is a path from every brother's house to the park and that a solution exists for each problem instance.

Output

Output should consist of one line of the form
Total miles driven: xxx

where xxx is the total number of miles driven by all the brothers' cars.

Sample Input

10
Alphonzo Bernardo 32
Alphonzo Park 57
Alphonzo Eduardo 43
Bernardo Park 19
Bernardo Clemenzi 82
Clemenzi Park 65
Clemenzi Herb 90
Clemenzi Eduardo 109
Park Herb 24
Herb Eduardo 79
3

Sample Output

Total miles driven: 183

题意:park最多连接k次,求一个最小不超过k度的生成树
思路:先将park点排除,构造生成树(可能是森林,s个联通块),再将park点加入,使之前的联通块联通
然后park点还剩k-s条边可以外连,这时候当我们再次任意连接其外的任何一点,都会形成一个环,那么就应该去除该环内
权值最大的边,利用dfs扫描各个联通块,记录从1到该点的路径中最大的一条的编号和权值。之后就进行删除操作,就此重复
 #include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
#include<iostream>
using namespace std; map<string,int>mp;
struct Node
{
int x,y,val;
}node[],dist[];
int fa[];
struct E
{
int y,next,val;
}edge[];
int n,cnt,tot,head[],k,tot2;
bool maps[][];
void add(int x,int y,int val)
{
edge[++tot].y=y;
edge[tot].val=val;
edge[tot].next=head[x];
head[x]=tot;
} bool cmp(Node a,Node b)
{
return a.val < b.val;
} int Find(int x)
{
return fa[x]==x?x:fa[x]=Find(fa[x]);
} void dfs(int s,int pre)
{
for(int i=head[s];i;i=edge[i].next)
{
int to = edge[i].y;
if(maps[s][to] && !dist[to].val)
{
if(edge[i].val < dist[s].val)dist[to] = dist[s];
else
{
dist[to].val = edge[i].val;
dist[to].y = to;
dist[to].x=s;
}
dfs(to,s);
}
}
}
int main()
{
cin>>n;
memset(maps,,sizeof(maps));
mp["Park"] = ;
tot = tot2 = ;
cnt = ;
for(int i=;i<=n;i++)
{
string name1,name2;
int val;
cin>>name1>>name2>>val;
if(!mp[name1])mp[name1] = ++cnt;
if(!mp[name2])mp[name2] = ++cnt;
add(mp[name1],mp[name2],val);
node[++tot2].x=mp[name1];
node[tot2].y=mp[name2];
node[tot2].val=val;
add(mp[name2],mp[name1],val);
}
for(int i=;i<=cnt;i++)fa[i]=i;
sort(node+,node++tot2,cmp);
scanf("%d",&k);
int ans=;
for(int i=;i<=tot2;i++)
{
int x=node[i].x;
int y=node[i].y;
if(x == || y == )continue;
int fx=Find(x);
int fy=Find(y);
if(fx != fy)
{
maps[x][y] = maps[y][x] = ;
fa[fx]=fy;
ans += node[i].val;
}
}
for(int i=;i<=tot2;i++)
{
int x=node[i].x;
int y=node[i].y;
if(x != && y != )continue;
int fx=Find(x);
int fy=Find(y);
if(fx!=fy)
{
maps[x][y] = maps[y][x] = ;
fa[fx]=fy;
ans+=node[i].val;
k--;
}
}
while(k--)
{
memset(dist,,sizeof(dist));
dfs(,);
int minn = 0x3f3f3f3f;
int id=;
for(int i=head[];i;i=edge[i].next)
{
int to = edge[i].y;
if(maps[][to])continue;
if(minn > edge[i].val - dist[to].val)
{
minn = edge[i].val - dist[to].val;
id = i;
}
}
if(minn >=)break;
int to = edge[id].y;
maps[][to] = maps[to][] = ;
maps[dist[to].x][dist[to].y] = maps[dist[to].y][dist[to].x] = ;
ans += minn;
}
printf("Total miles driven: %d\n",ans);
}

Picnic Planning POJ - 1639(最小k度生成树)的更多相关文章

  1. POJ 1639 Picnic Planning 最小k度生成树

    Picnic Planning Time Limit: 5000MS   Memory Limit: 10000K Total Submissions:11615   Accepted: 4172 D ...

  2. poj 1639 最小k度限制生成树

    题目链接:https://vjudge.net/problem 题意: 给各位看一下题意,算法详解看下面大佬博客吧,写的很好. 参考博客:最小k度限制生成树 - chty - 博客园  https:/ ...

  3. Picnic Planning POJ - 1639(度限制生成树)

    解题报告   题意理解 给定一张N个点,M个边的无向图,求出无向图的一颗最小生成树,但是我们要求一号节点的入度不可以超过给定的整数S 也就是一个最小生成树,要求它的一号节点,最多只能和S个节点相连. ...

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

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

  5. 最小k度限制生成树

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

  6. [POJ 1639] Picnic Planning

    [题目链接] http://poj.org/problem?id=1639 [算法] 首先,我们可以用深度优先遍历求出1号节点去除后有几个联通块 设共有T个联通块,若T > K则无解,否则 : ...

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

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

  8. poj1639,uva1537,uvalive2099,scu1622,fzu1761 Picnic Planning (最小限制生成树)

    Picnic Planning Time Limit: 5000MS   Memory Limit: 10000K Total Submissions: 10742   Accepted: 3885 ...

  9. K度限制MST poj 1639

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

随机推荐

  1. java基础-容器-Set

    Set:set不存重复元素,如果是使用set存储java预定义的Integer,String等类型会很简单,如果是存储自定义类型的数据类型,就必须要重新定义equals()方法以确保set中保存的对象 ...

  2. Vue学习笔记二:v-cloak,v-text,v-html的使用

    目录 v-cloak:解决插值表达式闪烁问题 安装插件Live Server 右键以HTTP形式运行HTML v-text:以属性方式使用插值表达式 v-cloak和v-text的区别 v-html: ...

  3. Python的安装及小程序练习

    Python 1.Python的安装教程 (1)进入Python官网 (2)双击Python-3.6.4.exe安装程序,勾选Add Python 3.6 to PATH (3)选择自定义安装. (4 ...

  4. 学习笔记-canny边缘检测

    Canny边缘检测 声明:阅读本文需要了解线性代数里面的点乘(图像卷积的原理),高等数学里的二元函数的梯度,极大值定义,了解概率论里的二维高斯分布 1.canny边缘检测原理和简介 2.实现步骤 3. ...

  5. vo类,model类,dto类的作用及划分

    1.entity里的每一个字段,与数据库相对应, 2.dto里的每一个字段,是和你前台页面相对应, 3.VO,这是用来转换从entity到dto,或者从dto到entity的中间的东西.   举个例子 ...

  6. C# - 设计模式 - 虚模式

    虚模式 问题场景 子类从抽象派生是为了解耦,但为了适应新的变化,可能需要向抽象类添加新功能,假如在添加新功能之前已经有100个子类实现了抽象,那么接下来你得在100个子类中去重写向抽象添加的新功能. ...

  7. JAVA实例

     JAVA实例1  1 package Demo3; import java.io.File; import java.io.FileReader; import java.io.IOExceptio ...

  8. json中的json.dumps()

    Json简介 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.它基于JavaScript(Standard ECMA-262 3rd Edition - ...

  9. Go命令官方指南【原译】

    启动错误报告 编译包和依赖项 删除目标文件和缓存的文件 显示包或符号的文档 打印Go环境信息 更新包以使用新API Gofmt(重新格式化)包源 通过处理源生成Go文件 下载并安装包和依赖项 编译并安 ...

  10. 生活日历NABCD需求分析

    这次我们团队要开发一个生活日历APP,对于这个APP的NABCD的需求分析,我对此作出其中的一小部分介绍. N(Need)需求 目前市场上有很多的日历程序,每个手机自带的功能中必然有日历程序.但是对于 ...