poj 1639 Picnic Planning 度限制mst
https://vjudge.net/problem/POJ-1639
题意:
有一群人,他们要去某一个地方,每个车可以装无数个人,给出了n条路,包含的信息有路连接的地方,以及路的长度,路是双向的,但是终点只有一个,并且终点能停的车的数量是有限制的,问最少走的路是多少。
思路:
因为终点的停车的数量是有限制的,所以终点的度是有限制的,又因为这题可以用最小生成树解决,所以就是度限制最小生成树。
度限制最小生成树求解思想并不复杂,首先我们把有度限制的点给忽略,然后给每一个连通分量求最小生成树,最后把每一个连通分量中与有度限制的点的距离最小的点与度限制点连接,假设有m个连通分量。
那么我们现在求出了m限制的最小生成树,假如限制数k < m,那么就无解。
当k >= m时,我们可以在m度限制mst的基础上,求m + 1,m + 2。。。k度限制最小生成树,求法也不是很难懂,但是程序就很难写了Orz。
如何求呢?枚举每一条未在生成树中与(现在我们把度限制点叫做R点)R点相连的边,然后把边加入生成树,必然会形成环,然后把环中与R点不相连的权值最大的边去掉,枚举之后的最小值就是m+1度限制最小生成树的值。然后依次求到k限制mst,求其中的最小值。
但是,依次枚举的话时间复杂度非常高,所以我们要优化。这时就用到了动态规划的思想。将与R点到其它点的边权值最大求出,之后加边的时候,直接替换就可以了。
转移方程 dp[v] = max(dp[father(v)],w(v , father(v)));
看不懂就多看几遍Orrrrrrrrrrrrrrrrrrrrrrrrz。
代码:
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
#include <map>
#include <string>
using namespace std; const int inf = 0x3f3f3f3f; struct edge
{
int x,y;
int v;
} a[],dp[]; map<string,int> mmp;
bool flag[][];
int par[];
int g[][]; int ans;
int num;
int du,lim; int fin(int x)
{
if (x == par[x]) return x;
else return par[x] = fin(par[x]);
} void unit(int x,int y)
{
x = fin(x);
y = fin(y); if (x == y) return; par[x] = y;
} void dfs(int cur,int pre)
{
for (int i = ;i <= num;i++)
{
if (i != pre && flag[cur][i])
{
if (dp[i].v == -)
{
if (dp[cur].v > g[cur][i])
{
dp[i] = dp[cur];
}
else
{
dp[i].x = cur;
dp[i].y = i;
dp[i].v = g[cur][i];
}
} dfs(i,cur);
}
}
} void solve(void)
{
for (int i = du + ;i <= lim;i++)
{
memset(dp,-,sizeof(dp)); dp[].v = -inf; for (int j = ;j <= num;j++)
if (flag[j][]) dp[j].v = -inf; dfs(,-); int mi = inf,tmp; for (int j = ;j <= num;j++)
{
if (g[][j] != -)
{
if (mi > g[][j] - dp[j].v)
{
mi = g[][j] - dp[j].v;
tmp = j;
}
}
} if (mi >= ) break; ans += mi; int x = dp[tmp].x,y = dp[tmp].y; flag[x][y] = flag[y][x] = ; flag[][tmp] = flag[tmp][] = ;
}
} int get_num(string aa)
{
if (mmp[aa]) return mmp[aa];
else
{
mmp[aa] = ++num;
return num;
}
} bool cmp(edge aa,edge bb)
{
return aa.v < bb.v;
} int main()
{
num = ; mmp["Park"] = ; memset(g,-,sizeof(g)); int n; scanf("%d",&n); for (int i = ;i < n;i++)
{
string aa,bb;
int v; cin >> aa >> bb; scanf("%d",&v); int x = get_num(aa),y = get_num(bb); if (g[x][y] == -) g[x][y] = g[y][x] = v;
else g[x][y] = g[y][x] = min(v,g[x][y]); a[i].x = x;
a[i].y = y;
a[i].v = g[x][y];
} for (int i = ;i <= num;i++) par[i] = i; scanf("%d",&lim); sort(a,a+n,cmp); for (int i = ;i < n;i++)
{
int x = a[i].x,y = a[i].y; if (x == || y == ) continue;
if (fin(x) == fin(y)) continue; ans += a[i].v; unit(x,y); flag[x][y] = flag[y][x] =;
} int minn[],tmp[]; memset(minn,inf,sizeof(minn)); for (int i = ;i <= num;i++)
{
int rt = fin(i); if (g[][i] != -)
{
if (g[][i] < minn[rt])
{
minn[rt] = g[][i];
tmp[rt] = i;
}
}
} for (int i = ;i <= num;i++)
{
if (minn[i] != inf)
{
du++;
flag[][tmp[i]] = flag[tmp[i]][] = ;
ans += minn[i];
}
} solve(); printf("Total miles driven: %d\n",ans); return ;
}
poj 1639 Picnic Planning 度限制mst的更多相关文章
- POJ 1639 Picnic Planning 最小k度生成树
Picnic Planning Time Limit: 5000MS Memory Limit: 10000K Total Submissions:11615 Accepted: 4172 D ...
- POJ 1639 Picnic Planning:最小度限制生成树
题目链接:http://poj.org/problem?id=1639 题意: 给你一个无向图,n个节点,m条边,每条边有边权. 让你求一棵最小生成树,同时保证1号节点的度数<=k. 题解: 最 ...
- [POJ 1639] Picnic Planning
[题目链接] http://poj.org/problem?id=1639 [算法] 首先,我们可以用深度优先遍历求出1号节点去除后有几个联通块 设共有T个联通块,若T > K则无解,否则 : ...
- POJ 1639 Picnic Planning(最小度限制生成树)
Description The Contortion Brothers are a famous set of circus clowns, known worldwide for their inc ...
- poj 1639 最小k度限制生成树
题目链接:https://vjudge.net/problem 题意: 给各位看一下题意,算法详解看下面大佬博客吧,写的很好. 参考博客:最小k度限制生成树 - chty - 博客园 https:/ ...
- K度限制MST poj 1639
/* k度限制MST:有一个点的度<=k的MST poj 1639 要求1号点的度不超过k 求MST 我们先把1号点扔掉 跑MST 假设有sum个连通分支 然后把这sum个分支连到1上 就得到了 ...
- poj1639,uva1537,uvalive2099,scu1622,fzu1761 Picnic Planning (最小限制生成树)
Picnic Planning Time Limit: 5000MS Memory Limit: 10000K Total Submissions: 10742 Accepted: 3885 ...
- POJ1639 - Picnic Planning
原题链接 Description 给出一张个点的无向边权图并钦定点,求使得点的度不超过的最小生成树. Solution 首先无视掉与相连的所有边,原图会变成若干互不连通的个块.对每个块分别求MST,再 ...
- 【POJ 1639】 Picnic Planning (最小k度限制生成树)
[题意] 有n个巨人要去Park聚会.巨人A和先到巨人B那里去,然后和巨人B一起去Park.B君是个土豪,他家的停车场很大,可以停很多车,但是Park的停车场是比较小.只能停k辆车.现在问你在这个限制 ...
随机推荐
- LeNet-5识别MINIST数据集
LeNet-5 LeNet于90年代被提出,鉴于当时的计算能力和内存容量,直到2010年才能真正的实施这样的大规模计算.LeNet-5是LeCun于1998年提出的深度神经网络结构,总共包含7层网络( ...
- Docker 网络管理及容器跨主机通信
1.网络模式 docker支持四种网络模式,使用--net选项指定: host,--net=host,如果指定此模式,容器将不会获得一个独立的network namespace,而是和宿主机共用一个. ...
- webpack.config.js文件的高级配置
一.多个入口文件之前我们配置的都是 一个入口 var webpack = require('webpack'); var commonsPlugin = new webpack.optimize.Co ...
- 基于hi-nginx的web开发(python篇)——utf-8编码
一致地utf-8编码,非常重要.对python2而言,尤其如此. 如果在hi-nginx中使用的是python2,同时又需要无障碍地使用中日韩等文字,那么一定不要忘记使用: #-*- coding:u ...
- 2018上C语言程序设计(高级)作业- 第1次作业
未来两周学习内容 复习指针的定义和引用 指针的应用场景: 指针作为函数参数(角色互换) 指针作为函数的参数返回多个值 指针.数组和地址间的关系 使用指针进行数组操作 数组名(指针)作为函数参数(冒泡排 ...
- 网易云音乐APP分析
网易云音乐-感受音乐的力量 你选择的产品是? 网易云音乐 为什么选择该产品作为分析? 之前用的一直是QQ音乐,但是有一天一个朋友分享了一首网易云上的音乐(顺便分享一下歌名:Drop By Drop) ...
- 《结对-HTML贪吃蛇游戏项目-测试过程》
项目托管平台地址:https://gitee.com/zhaojianhuiAA/TanChiShe/blob/master/snake.html 项目成员:赵建辉.马壮. 测试: 1.界面:用jav ...
- 2017-2018-1 Java演绎法 第三周 作业
团队任务:团队展示与选题 团队展示 队员学号及姓名 学号 姓名 主要负责工作 20162315 马军 日常统计,项目部分代码 20162316 刘诚昊 项目部分代码,代码质量测试 20162317 袁 ...
- bug终结者 团队作业第四、五周
bug终结者 团队作业第四.五周 博客编辑者:20162322朱娅霖 本周学习任务: 团队协作完成<需求规格说明书> 工作流程 第四周 团队成员各自完成蓝墨云班课中<需求规格说明书& ...
- 201621123040《Java程序设计》第5周学习总结
1.本周学习总结 1.1写出你认为本周学习中比较重要的知识点关键词 关键词:接口 Comparable Comparator 比较排序 1.2尝试使用思维导图将这些关键词组织起来.注:思维导图一般不需 ...