POJ 1639 Picnic Planning 最小k度生成树
| Time Limit: 5000MS | Memory Limit: 10000K | |
| Total Submissions:11615 | Accepted: 4172 |
Description
Input
Output
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 思路
一开始在网上搜索题解,照着他们的算法写,写完了才发现,他们有最重要的一步没有讲,幸好此时峰巨告诉了我算法的全过程,orz orz orz。 算法:
1.无视Park及其它的边,建立最小生成树(森林)。
2.选择park到每个树的最短边,与树相连。
3.此时,park到每棵树还剩了一些边,枚举他们,每一条边加进去都会有一个环,删去环内的最大边。枚举的时候不要真实操作(或者操作后还原),而是记录他们的值,选择最大的,再进行删边操作。
4.重复第三步(k-第一步最小生成树的数目)次 博主水平不高,如需帮助,请在下方留言
#include<iostream>
#include<vector>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
const int inf = ;
int mp[][],pp;
int dis[],disx[],n,k,kk;
int book[],flag[][];
char name[][];
int e1,e2,f[];
bool vis[];
int fo[];
struct node
{
int pio;
int wei;
int ex1,ex2;
}getr[],exa; int prim(int k)
{
dis[k]=;
int ans=; while(true){
int t=;
for(int i=;i<=n;i++){
if(!book[i]&&dis[i]<dis[t]){
t=i;
}
}
if(t==){break;}
ans+=dis[t];book[t]=k;flag[disx[t]][t]=flag[t][disx[t]]=true;
for(int i=;i<=n;i++){
if(!book[i]&&dis[i]>mp[t][i]){
dis[i]=mp[t][i];
disx[i]=t;
}
} }
return ans;
} void init()
{
for(int i=;i<=;i++){
for(int j=;j<=;j++){
mp[i][j]=inf;
}
}
for(int i=;i<=;i++){
dis[i]=inf;
}
} void scan()
{
int s,x,y;
scanf("%d",&n);
char a[],b[];
int t=;
init();
for(int i=;i<=n;i++){
scanf("%s%s%d",a,b,&s);
x=y=-;
for(int j=;j<=t;j++){
if(!strcmp(name[j],a)){x=j;}
if(!strcmp(name[j],b)){y=j;}
}
if(x==-){x=++t;strcpy(name[t],a);}
if(y==-){y=++t;strcpy(name[t],b);}
mp[x][y]=mp[y][x]=s;
} scanf("%d",&k);
n=t;
} int dfs(int p)//找出环内最大边
{
vis[p]=true;
int ans=-,op; for(int i=;i<=n;i++){
if(flag[i][p]&&i==pp&&f[p]!=i){e1=i;e2=p;return mp[i][p];}
if(!vis[i]&&flag[i][p]){
f[i]=p;
op=dfs(i); if(op!=-){
if(op<mp[i][p]){e1=i;e2=p;return mp[i][p];}
else return op;
}
}
}
return ans;
} int solve(int p)
{ int tx=,ans=;pp=p;
for(int i=;i<=kk;i++){
tx=;
memset(getr,,sizeof(getr));
// cout<<endl;
// cout<<"第"<<i<<"次轮回"<<endl;
for(int j=;j<=n;j++){
if(flag[p][j]||mp[p][j]==inf){continue;}
memset(vis,,sizeof(vis));
flag[p][j]=flag[j][p]=true;
// cout<<"新增的边 "<<j<<"--"<<p<<endl;
int yj=dfs(p);
// cout<<"删除边的长度 "<<yj<<endl;
getr[tx].pio=j;getr[tx].wei=mp[p][j]-yj;
getr[tx].ex1=e1;getr[tx].ex2=e2;
tx++;
flag[p][j]=flag[j][p]=false;//还原
}
exa.pio=;exa.wei=inf;
for(int i=;i<n;i++){
if(exa.wei>getr[i].wei){exa=getr[i];}
}
// cout<<"最终的决定 "<<exa.ex1<<" "<<exa.ex2<<" "<<exa.pio<<" "<<exa.wei<<endl;
ans+=min(exa.wei,);
flag[p][exa.pio]=flag[exa.pio][p]=true;
flag[exa.ex1][exa.ex2]=flag[exa.ex2][exa.ex1]=false;
}
return ans;
} int main()
{
scan();
int p;
for(int i=;i<=n;i++){
if(!strcmp(name[i],"Park")){p=i;break;}
}
int m=,ans=;
book[p]=p;
for(int i=;i<=n;i++){
if(!book[i]){
m++;
ans+=prim(i);
}
}
// cout<<"初次最小生成树 "<<ans<<endl;
kk=k;
for(int i=;i<=m;i++){
int minn=inf,ss=-;;
for(int j=;j<=n;j++){
if(!flag[p][j]&&!vis[book[j]]&&mp[p][j]!=inf){
if(mp[j][p]<minn){minn=mp[j][p];ss=j;}
}
}
if(minn!=inf){
kk--;
ans+=mp[p][ss];vis[book[ss]]=true;
flag[p][ss]=flag[ss][p]=true;
}
}
// cout<<"最小m度生成树 "<<ans<<endl;
printf("Total miles driven: %d\n",ans+solve(p));
}
POJ 1639 Picnic Planning 最小k度生成树的更多相关文章
- [POJ 1639] Picnic Planning
[题目链接] http://poj.org/problem?id=1639 [算法] 首先,我们可以用深度优先遍历求出1号节点去除后有几个联通块 设共有T个联通块,若T > 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:最小度限制生成树
题目链接:http://poj.org/problem?id=1639 题意: 给你一个无向图,n个节点,m条边,每条边有边权. 让你求一棵最小生成树,同时保证1号节点的度数<=k. 题解: 最 ...
- poj 1639 Picnic Planning 度限制mst
https://vjudge.net/problem/POJ-1639 题意: 有一群人,他们要去某一个地方,每个车可以装无数个人,给出了n条路,包含的信息有路连接的地方,以及路的长度,路是双向的,但 ...
- POJ 1639 Picnic Planning(最小度限制生成树)
Description The Contortion Brothers are a famous set of circus clowns, known worldwide for their inc ...
- poj1639 Picnic Planning,K度限制生成树
题意: 矮人虽小却喜欢乘坐巨大的轿车,车大到能够装下不管多少矮人.某天,N(N≤20)个矮人打算到野外聚餐.为了集中到聚餐地点,矮人A 要么开车到矮人B 家中,留下自己的轿车在矮人B 家,然后乘坐B ...
- poj1639,uva1537,uvalive2099,scu1622,fzu1761 Picnic Planning (最小限制生成树)
Picnic Planning Time Limit: 5000MS Memory Limit: 10000K Total Submissions: 10742 Accepted: 3885 ...
- poj1639 Picnic Planning 最小度数限制生成树
题意:若干个人开车要去park聚会,可是park能停的车是有限的,为k.所以这些人要通过先开车到其它人家中,停车,然后拼车去聚会.另外,车的容量是无限的,他们家停车位也是无限的. 求开车总行程最短. ...
- 【POJ 1639】 Picnic Planning (最小k度限制生成树)
[题意] 有n个巨人要去Park聚会.巨人A和先到巨人B那里去,然后和巨人B一起去Park.B君是个土豪,他家的停车场很大,可以停很多车,但是Park的停车场是比较小.只能停k辆车.现在问你在这个限制 ...
随机推荐
- 21.PHP实现Word/Excel/PPT转换为PDF
参考文档: https://www.cnblogs.com/woider/p/7003481.html http://blog.csdn.net/aoshilang2249/article/detai ...
- windows 安装tensorflow
原文知乎:https://zhuanlan.zhihu.com/p/25778703 前言 看到Rstudio中开始支持Tensorflow,本人是欣喜若狂的,同时TensorFlow官网从16年9月 ...
- HTML中文本过长时自动隐藏末尾部分或中间等任意部分
一. 一般情况下,HTML字符串过长时都会将超过的部分隐藏点,方法如下: 设置CSS: .ellipsis-type{ max-width: 50px; ...
- CML\LVDS
LVDS和CML电平应用区别 https://wenku.baidu.com/view/6bb0066f011ca300a6c3908c.html
- 在没有 Emacs 的情况下使用 Org 模式
导读 每到年初似乎总有这么一个疯狂的冲动来寻找提高生产率的方法.新年决心,正确地开始一年的冲动,以及“向前看”的态度都是这种冲动的表现.软件推荐通常都会选择闭源和专利软件.但这不是必须的. 这是我 2 ...
- SpringBoot远程接口调用-RestTemplate使用
在web服务中,调度远程url是常见的使用场景,最初多采用原生的HttpClient,现采用Spring整合的RestTemplate工具类进行.实操如下: 1. 配置 主要用以配置远程链接的相关参数 ...
- BZOJ3291Alice与能源计划——匈牙利算法+模拟费用流
题目描述 在梦境中,Alice来到了火星.不知为何,转眼间Alice被任命为火星能源部长,并立刻面临着一个严峻的考验.为 了方便,我们可以将火星抽象成平面,并建立平面直角坐标系.火星上一共有N个居民点 ...
- BZOJ3812 主旋律(状压dp+容斥原理)
设f[S]为S点集是SCC的方案数.考虑通过去掉不合法方案转移.可以枚举入度为0的SCC所含点集S',这样显然S^S'内部的边和由S'连向S^S'的边删还是不删任选.但是这样无法保证S'包含所有入度为 ...
- ElasticHD Windows环境下安装
ElasticHD Linux环境下安装教程 ElasticHD windows环境下安装教程 习惯了T-SQL 查询,Elasticsearch的DSL查询语法简直就是反人类呀,一 ...
- 【HDU - 4340】Capturing a country(树形DP)
BUPT2017 wintertraining(15) #8A 题意 n(<100)个城市组成的树.A攻击i城市需要a[i]代价,B需要b[i].如果一个城市的邻居被A攻击了,那么A攻击它只要A ...