博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj1639 Picnic Planning 最小度数限制生成树
阅读量:7202 次
发布时间:2019-06-29

本文共 2197 字,大约阅读时间需要 7 分钟。

题意:若干个人开车要去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 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;const int maxn =111+5;const int maxe = 15000+5;const int INF = 460002326;#include
map
mp;map
::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
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
cost[i][Min_i]) { num[i]=Min_i; dis[i]=cost[i][Min_i]; } } } Min=INF; int root=-1; for(int i=0; i
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
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
>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; }

转载地址:http://prwum.baihongyu.com/

你可能感兴趣的文章
NIO入门系列之第8章:连网和异步 I/O
查看>>
Dynamics CRM 给视图配置安全角色
查看>>
nginx基本配置与参数说明
查看>>
ssh免密码登录
查看>>
Linux文件查找命令find,xargs详述
查看>>
keepalived+nginx+lvs 实现web群集高可用性
查看>>
分布式系统面试连环炮
查看>>
C# 对IOC的理解 依赖的转移
查看>>
LINQ中的一些查询语句格式
查看>>
.htaccess 一段神奇的跳转代码
查看>>
前端框架
查看>>
深入理解linux的权限设置和SUID,SGID以及粘滞位
查看>>
size_t
查看>>
flask对json的内置处理模块jsonify
查看>>
树状数组
查看>>
(转)页面过度动画效果大集合
查看>>
常用js
查看>>
201609-4交通规划 不知道错哪了
查看>>
Spring Cloud 微服务入门(二)--Spring Cloud 架构
查看>>
typeahead自动补全插件的limit参数问题
查看>>