POJ1629:picnic planning
题目描述
矮人虽小却喜欢乘坐巨大的轿车,轿车大到可以装下无论多少矮人。某天,N(N≤20)个矮人打算到野外聚餐。为了
集中到聚餐地点,矮人A 有以下两种选择
1)开车到矮人B家中,留下自己的轿车在矮人B家,然后乘坐B的轿车同行
2)直接开车到聚餐地点,并将车停放在聚餐地。虽然矮人的家很大,可以停放无数量轿车,但是聚餐地点却最多只能停放K辆轿车。
现在给你一张加权无向图,它描述了N个矮人的家和聚餐地点,要你求出所有矮人开车的最短总路程。
输入格式
第一行是整数M,接下来M行描述了M条道路。
每行形式如同:S1 S2 x,S1和S2均是由字母组成长度不超过20的字符串
(特别地,当该字符串为”Park”时表示聚餐地点),x是整数,表示从S1到S2的距离。
最后一行包含单独的整数k.
输出格式
仅一行,形式如同:
Total miles driven: xxx
xxx是整数,表示最短总路程。
设Park为1节点。
先不考虑1节点,我们求出去掉1节点之后的图的最小生成树森林。设森林包含x棵树,那么我们从每棵树上都找出一条最短的连向1节点的边连起来。
然后我们可以再给1节点加上k-x条边。扫描1节点连接的所有还没被加入生成树的边,设其边长为p,两个端点为u,v,我们求出u和v在生成树上的路径中的最大边,设其边长为q。如果p-q<0,那么把q删去,把p加上。直到扫描完所有边或者加了k-x条边时,我们便得到了题目所求的生成树。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<map>
#define maxn 31
using namespace std;
struct edge{
int u,v,w;
bool operator<(const edge &e)const{ return w<e.w; }
}e[maxn*maxn],dp[maxn];
int key[maxn],minedge[maxn];
int fa[maxn],g[maxn][maxn];
bool tree[maxn][maxn];
int n,m,k,ans;
map<string,int> id;
inline int read(){
register int x(0),f(1); register char c(getchar());
while(c<'0'||'9'<c){ if(c=='-') f=-1; c=getchar(); }
while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int get(int x){ return fa[x]==x?x:fa[x]=get(fa[x]); }
inline void kruskal(){
sort(e+1,e+1+m);
for(register int i=1;i<=n;i++) fa[i]=i;
for(register int i=1;i<=m;i++){
int u=e[i].u,v=e[i].v,w=e[i].w;
if(u==1||v==1||get(u)==get(v)) continue;
fa[get(u)]=get(v),tree[u][v]=tree[v][u]=true;
ans+=w;
}
}
void dfs(int u,int pre){
for(register int i=2;i<=n;i++) if(tree[u][i]){
if(i==pre) continue;
if(dp[i].w==-1){
if(dp[u].w>g[u][i]) dp[i]=dp[u];
else{
dp[i].w=g[u][i],dp[i].u=u,dp[i].v=i;
}
}
dfs(i,u);
}
}
inline void solve(){
register int cnt=0;
for(register int i=2;i<=n;i++) if(g[i][1]!=0x3f3f3f3f){
int col=get(i);
if(g[i][1]<minedge[col]) minedge[col]=g[i][1],key[col]=i;
}
for(register int i=1;i<=n;i++) if(minedge[i]!=0x3f3f3f3f){
cnt++,tree[key[i]][1]=tree[1][key[i]]=true;
ans+=g[1][key[i]];
}
for(register int i=cnt+1;i<=k;i++){
memset(dp,-1,sizeof dp);
dp[1].w=-0x3f3f3f3f;
for(register int j=2;j<=n;j++) if(tree[1][j]) dp[j].w=-0x3f3f3f3f;
dfs(1,1);
int d,mini=0x3f3f3f3f;
for(register int j=2;j<=n;j++) if(mini>g[1][j]-dp[j].w){
mini=g[1][j]-dp[j].w,d=j;
}
if(mini>=0) continue;
tree[1][d]=tree[d][1]=true,tree[dp[d].u][dp[d].v]=tree[dp[d].v][dp[d].u]=false;
ans+=mini;
}
}
int main(){
memset(g,0x3f,sizeof g),memset(minedge,0x3f,sizeof minedge);
m=read(),id["Park"]=++n;
for(register int i=1;i<=m;i++){
string a,b; cin>>a>>b;
if(!id[a]) id[a]=++n;
if(!id[b]) id[b]=++n;
e[i].u=id[a],e[i].v=id[b],e[i].w=read();
g[e[i].u][e[i].v]=g[e[i].v][e[i].u]=min(g[e[i].u][e[i].v],e[i].w);
}
k=read();
kruskal(),solve();
printf("Total miles driven: %d\n", ans);
return 0;
}
POJ1629:picnic planning的更多相关文章
- POJ1639 - Picnic Planning
原题链接 Description 给出一张个点的无向边权图并钦定点,求使得点的度不超过的最小生成树. Solution 首先无视掉与相连的所有边,原图会变成若干互不连通的个块.对每个块分别求MST,再 ...
- POJ 1639 Picnic Planning 最小k度生成树
Picnic Planning Time Limit: 5000MS Memory Limit: 10000K Total Submissions:11615 Accepted: 4172 D ...
- poj1639,uva1537,uvalive2099,scu1622,fzu1761 Picnic Planning (最小限制生成树)
Picnic Planning Time Limit: 5000MS Memory Limit: 10000K Total Submissions: 10742 Accepted: 3885 ...
- 【POJ 1639】 Picnic Planning (最小k度限制生成树)
[题意] 有n个巨人要去Park聚会.巨人A和先到巨人B那里去,然后和巨人B一起去Park.B君是个土豪,他家的停车场很大,可以停很多车,但是Park的停车场是比较小.只能停k辆车.现在问你在这个限制 ...
- Picnic Planning POJ - 1639(最小k度生成树)
The Contortion Brothers are a famous set of circus clowns, known worldwide for their incredible abil ...
- POJ 1639 Picnic Planning(最小度限制生成树)
Description The Contortion Brothers are a famous set of circus clowns, known worldwide for their inc ...
- poj1639 Picnic Planning 最小度数限制生成树
题意:若干个人开车要去park聚会,可是park能停的车是有限的,为k.所以这些人要通过先开车到其它人家中,停车,然后拼车去聚会.另外,车的容量是无限的,他们家停车位也是无限的. 求开车总行程最短. ...
- poj 1639 Picnic Planning 度限制mst
https://vjudge.net/problem/POJ-1639 题意: 有一群人,他们要去某一个地方,每个车可以装无数个人,给出了n条路,包含的信息有路连接的地方,以及路的长度,路是双向的,但 ...
- POJ 1639 Picnic Planning:最小度限制生成树
题目链接:http://poj.org/problem?id=1639 题意: 给你一个无向图,n个节点,m条边,每条边有边权. 让你求一棵最小生成树,同时保证1号节点的度数<=k. 题解: 最 ...
随机推荐
- 如何push一个docker镜像到DockerHub上
在DockerHub上创建账号:https://hub.docker.com/ 这里我的账号是firewarm 本地下载镜像(这里拿alpine做示例),并为镜像打tag [root@host-30 ...
- 面试官让你讲讲Linux内核的竞争与并发,你该如何回答?
@ 目录 内核中的并发和竞争简介 原子操作 原子操作简介 整型原子操作函数 位原子操作函数 原子操作例程 自旋锁 自旋锁简介 自旋锁操作函数 自旋锁例程 读写自旋锁 读写锁例程 顺序锁 顺序锁操作函数 ...
- java中如何实现同一账号不能同时登录
经过两天的研究,下面给两个方法.不个是webwork版本的,一个是修改过后的网上的意见监听器版本的 (一) 首先先上自己的研究成果 1:首先在baseAction 中或者直接在action中写一个方法 ...
- java中将文件夹里面的文件复制到指定的文件夹(java IO)
//现在制定路径下创建名称为左侧的文件夹 public class Copy { public static void main(String[] args) { //原始文件地址 File srcF ...
- 内部类和Lambda
1.1 内部类的基本使用 在一个类中定义一个类.举例:在一个类A的内部定义一个类B,类B就被称为内部类 内部类定义格式 格式&举例: /* 格式: class 外部类名{ 修饰符 c ...
- JSP 的 4 种作用域?
page:代表与一个页面相关的对象和属性. request:代表与客户端发出的一个请求相关的对象和属性.一个请求可能跨越多个页面,涉及多个 Web 组件:需要在页面显示的临时数据可以置于此作用域. s ...
- Spring Boot中初始化资源的几种方式
CommandLineRunner 定义初始化类 MyCommandLineRunner 实现 CommandLineRunner接口,并实现它的 run()方法,在该方法中编写初始化逻辑 注册成Be ...
- [剑指 Offer 18. 删除链表的节点]
[剑指 Offer 18. 删除链表的节点] 给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点. 返回删除后的链表的头节点. 注意:此题对比原题有改动 示例 1: 输入: head ...
- (转) 增加 header 参数,spring boot + swagger2(springfox)
1 @Configuration 2 @EnableSwagger2 3 public class Swagger2 { 4 @Bean 5 public Docket createRestApi() ...
- github下载大文件太慢/失败
场景 github下载大文件,使用浏览器下载zip包到本地在下载到1G时失败, 使用 git clone ssh下载速度20k/s以下,已fq. 解决方法(亲测) 1.下载Github Desktop ...