题意:若干个人开车要去park聚会,可是park能停的车是有限的,为k。所以这些人要通过先开车到其它人家中,停车,然后拼车去聚会。另外,车的容量是无限的,他们家停车位也是无限的。

求开车总行程最短。

就是求一最小生成树,可是对于当中一个点其度不能超过k。

思路:

1. 将park点取出 将剩下的点求出最小生成树  出现i个联通块

2. 再每一个块中选择与park点相邻的最小边

到此park点已经连了i条边

park点最大能够连接k个点

得到Sum值

3. 须要求出i+1-->k 条的Sum值

每次加入一条边在树上形成一个环 然后 删去一条环上的边(权值最大)取Sum=min(Sum,Sum+加入边-删去边)  复杂度O(n^2)

由于第三步复杂度高须要优化第三步

优化:先记录Vi->Vp路径上且不与Vp直接相连的边的权值的Max[ i ]

加入边时 取cost(Vi,Vp)-Max [ i ]最小值 加入(Vi,Vp)边

再枚举ViVp原有的路径上不与Vp相连的边,找到最大权值的边;

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <malloc.h>
#include <ctype.h>
#include <math.h>
#include <string>
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;
const int maxn =111+5;
const int maxe = 15000+5;
const int INF = 460002326;
#include <map>
map<string,int>mp;
map<string,int>::iterator it;
int car,n,cost[maxn][maxn],sum,father[maxn];
int best[maxn];
bool vis[maxn];
bool edge[maxn][maxn];
bool use[maxn];
void dfs(int root)//将一个连通块中各个点标记其father
{
for(int i=1; i<n; i++)
{
if(vis[i]&&edge[root][i])
{
father[i]=root;
vis[i]=false;
dfs(i);
}
}
}
void prim(int s)
{
int Min_i,Min,dis[maxn],num[maxn];
memset(vis,false,sizeof(vis));
for(int i=0; i<n; i++)
{
dis[i]=cost[i][s];
num[i]=s;//此时dis[i]的值来自哪个点
}
dis[s]=0;
vis[s]=use[s]=true;
while(true)
{
Min=INF,Min_i=-1;
for(int i=0; i<n; i++)
{
if(!use[i]&&!vis[i]&&(Min_i==-1||Min>dis[i]))
{
Min_i=i;
Min=dis[i];
}
}
if(Min==INF) break;
sum+=Min;
vis[Min_i]=true;
use[Min_i]=true;//标记连通块用过的点
edge[Min_i][num[Min_i]]=edge[num[Min_i]][Min_i]=true;
for(int i=0; i<n; i++)
{
if(!use[i]&&!vis[i]&&dis[i]>cost[i][Min_i])
{
num[i]=Min_i;
dis[i]=cost[i][Min_i];
}
}
}
Min=INF;
int root=-1;
for(int i=0; i<n; i++)//寻找该连通块到Park点的最小距离
{
if(vis[i]&&cost[0][i]<Min&&i!=0)//在这棵树中
{
Min=cost[0][i];
root=i;
}
}
vis[root]=false;
dfs(root);//以root为根
father[root]=0;
sum+=Min;
}
int Best(int j)//更新当中各个点到park路径上边权值最大的点
{
if(father[j]==0)//假设father为0,记为-1
return best[j]=-1;
if(best[j]!=-1) return best[j];//假设已经存在 。直接返回
int tmp=Best(father[j]);
if(tmp!=-1)//这说明其父节点不与park相连
{
if(cost[tmp][father[tmp]]>cost[father[j]][j])
best[j]=tmp;
else best[j]=j;
}
else best[j]=j;//其父节点与source相连 将j赋给自己
return best[j];
}
void solve()
{
int mst=0;
memset(father,-1,sizeof(father));
memset(use,0,sizeof(use));
memset(edge,false,sizeof(edge));
use[0]=true;
for(int i=0; i<n; i++)
{
if(!use[i])//use用过要标记
{
prim(i);//除Park外建最小生成树
mst++;
}
}
for(int i=mst+1; i<n&&i<=car; i++)
{
memset(best,-1,sizeof(best));
for(int j=0; j<n; j++)
{
if(j!=0&&best[j]==-1&&father[j]!=0)
Best(j);
}
int minadd=INF;
int ax,bx,change;
for(int j=0; j<n; j++)
{
if(cost[0][j]!=INF&&father[j]!=0)
{
ax=best[j];
bx=father[ax];
if(minadd>cost[0][j]-cost[ax][bx])//cost[0][j]表示加入的边 cost[ax][bx]表示断开的边
{
minadd=cost[0][j]-cost[ax][bx];//更新减小的值以及连接的点
change=j;
}
}
}
if(minadd>=0) //表示要添加sum值 则已经得到最小的sum值
break;
sum+=minadd;//更新
ax=best[change];
bx=father[ax];
cost[ax][bx]=cost[bx][ax]=INF;
father[change]=0;
cost[0][change]=cost[change][0]=INF;
}
}
int main()
{
int t;
// freopen("in.txt","r",stdin);
cin>>t;
mp.clear();
string s1,s2;
int val;
for(int i=0; i<maxn; i++)
for(int j=0; j<maxn; j++)
cost[i][j]=INF;
n=1,sum=0;
mp["Park"]=0;//Park为0;
for(int i=0; i<t; i++)
{
cin>>s1>>s2>>val;
it=mp.find(s1);//map映射值
if(it==mp.end())
mp[s1]=n++;
it=mp.find(s2);
if(it==mp.end())
mp[s2]=n++;
if(cost[mp[s1]][mp[s2]]>val)//可能会有重边。其实没有。。。。 。
cost[mp[s1]][mp[s2]]=cost[mp[s2]][mp[s1]]=val;
}
cin>>car;
solve();
cout<<"Total miles driven: "<<sum<<endl;
return 0;
}

poj1639 Picnic Planning 最小度数限制生成树的更多相关文章

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

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

  2. POJ1639 - Picnic Planning

    原题链接 Description 给出一张个点的无向边权图并钦定点,求使得点的度不超过的最小生成树. Solution 首先无视掉与相连的所有边,原图会变成若干互不连通的个块.对每个块分别求MST,再 ...

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

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

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

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

  5. POJ-1639 Picnic Planning 度数限制最小生成树

    解法参考的论文:https://wenku.baidu.com/view/8abefb175f0e7cd1842536aa.html 觉得网上的代码好像都是用邻接矩阵来实现的,觉得可能数据量大了会比较 ...

  6. POJ1639 Picnic Planning (限制入度最小生成树)

    节点1是有度数限制的,把节点1去掉,就会形成若干个连通块,在每个连通块内部求最小生成树(prim算法实现),并求出每个连通块与1相连的最短的边,这样形成了初始状态的生成树. 假设(1,x)这条边没在生 ...

  7. POJ3241 最小曼哈顿距离生成树 - 真有趣哇

    目录 Catalog Solution: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 Catalog Problem:Portal传送门  原题目描述在最下面.  给你n个坐标, ...

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

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

  9. POJ 1639 Picnic Planning(最小度限制生成树)

    Description The Contortion Brothers are a famous set of circus clowns, known worldwide for their inc ...

随机推荐

  1. NOI08冬令营 数据结构的提炼与压缩

    无聊随手翻,翻到了一个这样的好东西--据结构的提炼与压缩: 为了防止以后忘记,这里把论文里的题目都纪录一下吧. 1.二维结构的化简 问题一:ural 1568 Train car sorting 定义 ...

  2. Java中的字符串驻留

    转自:http://www.cdtarena.com/javapx/201307/9088.html 最近在工作的时候,一句再正常不过的代码String a = “hello” + “world”;被 ...

  3. Windows 7 taskbar and startmenu pin

    原文 Windows 7 taskbar and startmenu pin 在Windows 7上,用户可以将自己喜欢的软件“钉”在开始菜单或任务栏,使用起来更加方便.但有时候我们也需要用程序来将这 ...

  4. perl学习(10) 字符串处理函数和排序

    1.1.index Perl 查找子串第一次在大字符串中出现的地方,返回第一个字符的位置. . . my $stuff = “Howordy world!”; my $where3 = index($ ...

  5. Swift - 邮件发送功能的实现

    使用MessageUI.framework框架除了可以发送短信,还能发送Email,步骤如下: (1)首先判断设备是否有发送邮件功能 (2)如果设备允许发送邮件,创建一个MFMailComposeVi ...

  6. 融云(找到“每个App都有沟通的需求”的细分市场)

    近日,国内著名App驾考宝典和融云达成合作,为应用增加IM功能,实现亿级用户之间聊天.消息一出,IM(即时通讯)领域的大佬,同时也是个上线不到两岁的新生力量,再次引发了行业的关注. 对业内人士而言,即 ...

  7. window2003远程桌面“已达最大连接数”

    使用命令行强制注销远程登录用户 Fri, 04/19/2013 - 09:29 - admin 来源地址: http://space.itpub.net/10067101/viewspace-6147 ...

  8. CWnd中PreCreateWindow、PreSubclassWindow、SubclassWindow的区别

    http://blog.csdn.net/swimmer2000/archive/2007/10/30/1856213.aspx MFC(VC6.0)的CWnd及其子类中,有如下三个函数:     / ...

  9. springboot 开发入门,及问题汇总

    1 . springboot简单介绍(http://projects.spring.io/spring-boot/) 现在的web项目几乎都会用到spring框架,而要使用spring难免需要配置大量 ...

  10. iOS UIButton详细介绍

    昨天,做了项目中的一点,觉得细节还是很重要的.像一个普通的UIButton,给它调试字体格式,大小什么的,确实是蛮耗时间的. 今天打算详细的归纳归纳.. typedef NS_ENUM(NSInteg ...