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辆车.现在问你在这个限制 ...
随机推荐
- 前端框架framework和库library的一点区别和记录
本篇纯文字,无关代码,只是一点概念的记录 关于所谓前端 首先学的是HTML5.CSS3.JavaScript这三个 之后接触了一下UI框架,如layui和bootstrap 目前是打算去学VUE和an ...
- tomcat 和jboss区别
参考http://blog.csdn.net/sz_bdqn/article/details/6762175
- 解析xml文件 selectSingleNode取不到节点
今天在做批量生成XML的时候,碰到一个情况 解析xml文件 selectSingleNode一直返回NULL. XML的格式开头有一句这个<CE401Message xmlns="ht ...
- Sql server 经典常用函数
..STUFF()用另一子串替换字符串指定位置.长度的子串.STUFF (<character_expression1>, <start_ position>, <len ...
- How to SHA1 on macOS
openssl sha1 /volumes/test/install/osx-test.dmg
- How to remove tag on Github
git tag -d 22 git push origin :refs/tags/22
- 启动docker容器 防火墙问题报错 ! -i docker0' failed: iptables: No chain/target/match by that name.
COMMAND_FAILED: '/sbin/iptables -t nat -A DOCKER -p tcp -d 0/0 --dport 8111 -j DNAT --to-destination ...
- Multiple websites on single instance of IIS
序幕 通常需要在单个IIS实例上托管多个网站,主要在开发环境中,而不是在生产服务器上.我相信它在生产服务器上不是一个首选解决方案,但这至少是一个可能的实现. Web服务器单实例上的多个网站的好处是: ...
- Nginx websocket反向代理
L:106 现在主流的反向代理,通过长链接可以从服务器推送数据到页面 升级成websocket反向代理必须根据上面的配置做配置 缺点无法多路复用,也就是没办法并行 我们测试下Websocket反向代理 ...
- 英特尔DRM内核驱动程序默认启用PSR2省电功能
导读 英特尔DRM/KMS内核驱动程序很快就会启用PSR2面板自刷新功能,以便在英特尔支持的超极本/笔记本电脑上实现更多节能. 一段时间以来,英特尔的Direct Rendering Manager驱 ...