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辆车.现在问你在这个限制 ...
随机推荐
- AVL树(Java实现)
AVL树基本介绍 AVL树是一种自平衡的二叉查找树,在AVL树中任何节点的两个子树的高度差不能超过1.就是相当于在二叉搜索树的基础上,在插入和删除时进行了平衡处理. 不平衡的四种情况 LL:结构介绍 ...
- 使用jitpack来获取github上的开源项目
在开发中我们需要经常使用第三方依赖库,在构建工具Gradle或maven中声明依赖, 大部分使用的是maven中心仓库或者阿里云仓库等等,但是这样也存在一个问题,上述仓库的库虽然简单快捷好用,但并不是 ...
- 笔记:Struts2 Action 非泛型集合元素类型转换
局部类型转换文件 局部类型转换文件的文件名应为 ActionName-conversion.properties,其中 ActionName 是需要替换为 Action 的类名称,后面的 conver ...
- nginx+lua 根据指定路径反向代理
location /imgproxytest{ if ($uri ~ ".*\.(jpg|png|jpeg|bmp|gif|swf|css)$"){ rewrite_by_lua ...
- cisco交换机实现端口聚合
0x00前言: 今天听老师讲端口聚合,为了方便日后复习故此有 了本篇随笔. 0x01准备工具: cisco模拟器 0x02:目录 为什么要用端口聚合? 广播风暴? 扩展:SMTP 0x03正文: 为什 ...
- 浅谈-RMQ
浅谈RMQ Today,我get到了一个新算法,开心....RMQ. 今天主要说一下RMQ里的ST算法(Sparse Table). RMQ(Range Minimum/Maximum Query), ...
- UGUI中显示粒子特效
今天在UGUI上显示粒子特效的时候遇到的一些问题,Mark一下.原理:修改特效中每一个ParticleSystem的Layer为UI,并且把ParticleSystemRenderer.sorting ...
- Sublime 、NotePad++中查找匹配中文字符
在Sublime .NotePad++中可以使用正则表达式 [\x{4e00}-\x{9fa5}] 查找匹配中文字符.
- alpha冲刺第五天
一.合照 二.项目燃尽图 三.项目进展 调整了一些界面的布局 细化了部分小功能的界面 注册界面和服务器响应了,但是在insert数据库方面出现了错误 四.明日规划 继续研究如何将注册的内容插入数据库 ...
- Markdown文本测试
一级标题 二级标题 三级标题 四级标题 五级标题 六级标题 1. 这是一 2. 这是二 这是无序符号 My Github 这是着重表示 这是斜体 一级粗体 二级斜体 cin >> a; c ...