解法参考的论文:https://wenku.baidu.com/view/8abefb175f0e7cd1842536aa.html

觉得网上的代码好像都是用邻接矩阵来实现的,觉得可能数据量大了会比较慢。于是自己写了一遍。

实现细节可以看代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<vector>
using namespace std;
const int N=+;
const int INF=0x3f3f3f3f;
int n,m,k,ans,fa[N];
struct edge{
int x,y,z;
bool used;
edge() {}
edge(int x,int y,int z) : x(x),y(y),z(z) { used=; }
bool operator < (const edge &rhs) const {
return z<rhs.z;
}
}e[N];
map<string,int> mp;
vector<int> G[N]; int getfa(int x) { return x==fa[x] ? x : fa[x]=getfa(fa[x]); } void kruskal() {
sort(e+,e+m+);
for (int i=;i<=n;i++) fa[i]=i;
for (int i=;i<=m;i++) {
int fx=getfa(e[i].x),fy=getfa(e[i].y);
if (e[i].x== || e[i].y== || fx==fy) continue;
fa[fy]=fa[fx];
e[i].used=;
ans+=e[i].z;
}
} int Max[N];
void dfs(int x,int f) {
for (int i=;i<G[x].size();i++) {
int y; if (e[G[x][i]].x==x) y=e[G[x][i]].y; else y=e[G[x][i]].x;
if (!e[G[x][i]].used || y==f) continue;
if (x!=) //这个很重要:去掉的边必须和V0不相连(否则会使得根节点度数减少)
if (Max[x]== || e[G[x][i]].z>e[Max[x]].z) Max[y]=G[x][i];
else Max[y]=Max[x];
dfs(y,x);
}
} int cnt=,Min[N];
void solve() {
memset(Min,,sizeof(Min));
for (int i=;i<G[].size();i++) { //把各个MST森林最小边连到根节点 变成一棵树
int ty;
if (e[G[][i]].x==) ty=getfa(e[G[][i]].y);
else ty=getfa(e[G[][i]].x);
if (Min[ty]== || e[G[][i]].z<e[Min[ty]].z) Min[ty]=G[][i];
}
for (int i=;i<=n;i++)
if (Min[i]) { cnt++; ans+=e[Min[i]].z; e[Min[i]].used=; } for (int i=cnt+;i<=k;i++) { //拓展根节点度数
memset(Max,,sizeof(Max));
dfs(,); //dfs找每个点到根节点的路径上的最长边
int minn=INF,New,Old;
for (int j=;j<G[].size();j++)
if (!e[G[][j]].used) {
int y; if (e[G[][j]].x==) y=e[G[][j]].y; else y=e[G[][j]].x;
if (Max[y]==) continue;
int tmp=e[G[][j]].z-e[Max[y]].z;
if (tmp<minn) { //记录本次结点拓展最大的收益
minn=tmp;
New=G[][j]; Old=Max[y];
}
}
if (minn>=) break;
ans+=minn;
e[New].used=; e[Old].used=; //替换最长边
}
} int main()
{
cin>>m;
string s1,s2; int x,y,z;
n=; mp["Park"]=;
for (int i=;i<=m;i++) {
cin>>s1>>s2>>z;
if (!mp.count(s1)) mp[s1]=++n;
if (!mp.count(s2)) mp[s2]=++n;
x=mp[s1]; y=mp[s2];
e[i]=edge(x,y,z);
}
cin>>k; kruskal(); //先忽略根节点做一次MST 得到MST森林
for (int i=;i<=m;i++) { G[e[i].x].push_back(i); G[e[i].y].push_back(i); }
solve(); //拓展根节点度数得到更小的MST printf("Total miles driven: %d\n",ans);
return ;
}

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

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

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

  2. POJ 1639 Picnic Planning:最小度限制生成树

    题目链接:http://poj.org/problem?id=1639 题意: 给你一个无向图,n个节点,m条边,每条边有边权. 让你求一棵最小生成树,同时保证1号节点的度数<=k. 题解: 最 ...

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

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

  4. [POJ 1639] Picnic Planning

    [题目链接] http://poj.org/problem?id=1639 [算法] 首先,我们可以用深度优先遍历求出1号节点去除后有几个联通块 设共有T个联通块,若T > K则无解,否则 : ...

  5. poj 1639 Picnic Planning 度限制mst

    https://vjudge.net/problem/POJ-1639 题意: 有一群人,他们要去某一个地方,每个车可以装无数个人,给出了n条路,包含的信息有路连接的地方,以及路的长度,路是双向的,但 ...

  6. UVA1537 Picnic Planning(思维+最小生成树)

    将1号点从图中去掉过后,图会形成几个连通块,那么我们首先可以在这些连通块内部求最小生成树. 假设有\(tot\)个连通块,那么我们会从1号点至少选\(tot\)个出边,使得图连通.这时我们贪心地选择最 ...

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

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

  8. POJ1639 - Picnic Planning

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

  9. 限制某个顶点度数的最小生成树 poj1639

    Picnic Planning Time Limit: 5000MS   Memory Limit: 10000K Total Submissions: 10642   Accepted: 3862 ...

随机推荐

  1. shell位置参数处理举例

  2. 关于Django路由层简单笔记

    Django—路由层 URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:你就是以这种方式告诉Django,对于客户端发来的某个U ...

  3. vector<类指针>清理

    https://www.cnblogs.com/nanke/archive/2011/05/10/2042662.html 1.vector<class> &aa,作为函数参数 2 ...

  4. oracle10G rac 10.2.0.1升级10.2.0.4

    前言 ocr版本查询指令:  ocrcheck vote盘路径查询指令: crsctl query css votedisk 相关指令参考来源:http://hzhg12345.blog.163.co ...

  5. java改动后运行无变化

    缓存没有及时清理,重新清理打包后运行正常

  6. 阿里云ssh免密登陆突然无效

    [root@node03 ~]# ssh-copy-id node02 root@node02's password: sh: .ssh/authorized_keys: Permission den ...

  7. 【POM】maven profile切换正式环境和测试环境

    有时候,我们在开发和部署的时候,有很多配置文件数据是不一样的,比如连接mysql,连接redis,一些properties文件等等 每次部署或者开发都要改配置文件太麻烦了,这个时候,就需要用到mave ...

  8. Python--nfs服务+计划任务crond服务+shell介绍

    nfs服务 NFS 是Network File System的缩写,即网络文件系统. 功能是通过网络让不同的机器.不同的操作系统能够彼此分享个别的数据,让应用程序在客户端通过网络访问位于服务器磁盘中的 ...

  9. ofbiz:找不到org.ofbiz.widget.ContentWorkerInterface的类文件

    ofbiz编译报错: 找不到org.ofbiz.widget.DataResourceWorkerInterface的类文件 找不到org.ofbiz.widget.ContentWorkerInte ...

  10. hdu 3060 Area2 (计算几何模板)

    Problem Description 小白最近又被空军特招为飞行员,参与一项实战演习.演习的内容还是轰炸某个岛屿(这次的岛屿很大,很大很大很大,大到炸弹怎么扔都能完全在岛屿上引爆),看来小白确实是飞 ...