解法参考的论文: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. 关于ovf导入到Esxi上出显的“文件条目(行1)无效,sha256……”处理办法

    通常删除同名文件*.mf文件即可导入!

  2. Linux文件压缩、解压缩及归档工具一

    主题Linux文件压缩.解压缩及归档工具 压缩工具很重要的,因为要经常到互联网下载包 一compress/uncompress compress [-dfvcVr] [-b maxbits] [fil ...

  3. Mac上的Apache 开启,停止,重启

    sudo apachectl -k start     启动 sudo apachectl -k stop     停止   sudo apachectl -k restart   重启

  4. Python--基础之socket编程

    一 客户端/服务器架构 即C/S架构,包括 1.硬件C/S架构(打印机) 2.软件C/S架构(web服务) 美好的愿望: 最常用的软件服务器是 Web 服务器.一台机器里放一些网页或 Web 应用程序 ...

  5. ofbiz webservice 例解

    1.定义controller.xml文件,controller文件:ofbiz当前项目的所有请求的入口,通过对应request-map:将所有的请求uri对应到指定的处理函数上. <reques ...

  6. MTD系统架构和yaffs2使用、Nandflash驱动设计

    一.MTD系统架构 1.MTD设备体验 FLASH在嵌入式系统中是必不可少的,它是bootloader.linux内核和文件系统的最佳载体. 在Linux内核中引入了MTD子系统为NORFLASH和N ...

  7. BN和正则化一起使用的后果

    就是因为 batch norm 过后, weight 影响没那么重了,所以 l2 weight decay 的效果就不明显了. 证明了L2正则化与归一化相结合时没有正则化效应.相反,正则化会影响权重的 ...

  8. linux查看java jdk jre安装路径和设置环境变量

    一. 查看java jdk安装路径和设置环境变量 windows: set java_home:查看JDK安装路径 java -version:查看JDK版本 linux: whereis java ...

  9. nginx添加一个server

    nginx添加一个server server { listen 80; server_name dev.pccb.com; index index.html index.htm; # rewrite ...

  10. angularjs &登录跳转

    如果要使用$location,$stateParams,那么必须有相应形参controller: function ($rootScope, $http, $scope, $state,$locati ...