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. Apache Hadoop 2.9.2 完全分布式部署

    Apache Hadoop 2.9.2 完全分布式部署(HDFS) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.环境准备 1>.操作平台 [root@node101.y ...

  2. 各类聚类(clustering)算法初探

    1. 聚类简介 0x1:聚类是什么? 聚类是一种运用广泛的探索性数据分析技术,人们对数据产生的第一直觉往往是通过对数据进行有意义的分组.很自然,首先要弄清楚聚类是什么? 直观上讲,聚类是将对象进行分组 ...

  3. ElasticSearch query_string vs multi_match cross_fields query

    ElasticSearch query_string vs multi_match cross_fields query 本文记录以字段为中心的查询和以词为中心的查询这两种查询方式的区别以及在Elas ...

  4. What is the difference between __str__ and __repr__ in Python

    from https://www.pythoncentral.io/what-is-the-difference-between-__str__-and-__repr__-in-python/ 目的 ...

  5. arcgis图层 GraphicsLayer与FeatureLayer

    什么是图层 图层是用来在 ArcGIS 产品套件中显示地理数据集的机制.每个图层代表一种数据集(可以是地图服务.图形或是矢量数据),并指定该数据集是如何描绘使用一组属性的. 包含一个地图控件的每个应用 ...

  6. 解决MySQL Access denied for user 'root'@'IP地址' 问题

    1.mysql -u root -p 登陆进MYSQL: 2.执行以下命令: GRANT ALL PRIVILEGES ON *.* TO 'your name'@'%' IDENTIFIED BY ...

  7. Java Socket 服务端发送数据 客户端接收数据

    服务端: package com.thinkgem.wlw.modules.api.test.socket; /** * @Author: zhouhe * @Date: 2019/4/8 9:30 ...

  8. git 解决每次更新代码都要输入用户名密码的解决方案

    使用git pull或者git push每次都需要输入用户名和密码很繁琐,耽误时间,现在教大家一条命令实现保存用户名和密码不用再输入 git config --global credential.he ...

  9. 关于vscode插件 的一些体验

    一 vsCode git 首先vscode 继承了 git 在使用git前 先手动创建一个文件夹  用来clone已有项目 然后将 clone下来的项目放入工作区 右上角的小转转就是 pull文件 更 ...

  10. day05 数据类型的方法详解

    今日内容: 1.数字的基本操作 2.字符串的操作及常用方法 3.列表的操作及常用方法 重点: 1.字符串的操作及常用方法 (1)常用操作 """ 字符串的操作: &quo ...