AcWing 野餐规划

Description

  • 一群小丑演员,以其出色的柔术表演,可以无限量的钻进同一辆汽车中,而闻名世界。

    现在他们想要去公园玩耍,但是他们的经费非常紧缺。

    他们将乘车前往公园,为了减少花费,他们决定选择一种合理的乘车方式,可以使得他们去往公园需要的所有汽车行驶的总公里数最少。

    为此,他们愿意通过很多人挤在同一辆车的方式,来减少汽车行驶的总花销。

    由此,他们可以很多人驾车到某一个兄弟的家里,然后所有人都钻进一辆车里,再继续前进。

    公园的停车场能停放的车的数量有限,而且因为公园有入场费,所以一旦一辆车子进入到公园内,就必须停在那里,不能再去接其他人。

    现在请你想出一种方法,可以使得他们全都到达公园的情况下,所有汽车行驶的总路程最少。

Input

  • 第一行包含整数n,表示人和人之间或人和公园之间的道路的总数量。

    接下来n行,每行包含两个字符串A、B和一个整数L,用以描述人A和人B之前存在道路,路长为L,或者描述某人和公园之间存在道路,路长为L。

    道路都是双向的,并且人数不超过20,表示人的名字的字符串长度不超过10,公园用“Park”表示。

    再接下来一行,包含整数s,表示公园的最大停车数量。

    你可以假设每个人的家都有一条通往公园的道路。

Output

  • 输出“Total miles driven: xxx”,其中xxx表示所有汽车行驶的总路程。

Sample Input

10
Alphonzo Bernardo 32
Alphonzo Park 57
Alphonzo Eduardo 43
Bernardo Park 19
Bernardo Clemenzi 82
Clemenzi Park 65
Clemenzi Herb 90
Clemenzi Eduardo 109
Park Herb 24
Herb Eduardo 79
3

Sample Output

Total miles driven: 183

题解:

  • 最小生成树,最小k度生成树。

  • 这题废话贼多,下面为翻译版本:给定一张N个点M条边的无向图,求出无向图的一棵最小生成树,满足1号节点的度数不超过给定的整数S。N <= 30。
  • 如果度数无限制直接最小生成树就行了。那么现在对1号点有了限制。那我可以先不看1号点啊,即断掉与1号点相连的所有边。这样,一张图就被分成了若干个联通块(假设为T块。那么我们贪心的想,肯定是对这若干个联通块每块做一次最小生成树。这样肯定是最优的。那么做完T后,我们再从每个联通块中选一个点到1号点权值最小的连上。这样,我们就完美的得到了一个恰好T度的最小生成树。注意,恰好T度,说明什么,如果T < S的话,我们还可以将这棵T度生成树变成一个S/S - 1/S - 2/…/T + 1度生成树,说不定会更优呢!所以这时枚举与1相连的点x,如果x到1的边不在生成树中,那么就可以得到一个赚到的价值v = 生成树中1到x路径上最大的边权 - x到1的边权。每一轮取一个最大的赚到价值,进行S - T轮后退出。或者一旦最大赚到价值 < 0了,也退出。
  • 我已经尽梨讲得明白了…
  • 写这题要有一定的码力

#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#include <algorithm>
#define N 35
#define M 100005
#define inf 0x7fffffff
using namespace std;struct E {int next, to, dis;} e[M], edge[M];
struct Ed {int u, v, w;} ed[M];
int n = 1, m, S, T, num, num_edge, ans, tot, g;
int h[N], fat[N], head[N], Max[N];
bool vis[N], tag[N], fromOne[N];
map<string, int> mp;
map<string, bool> b;void add(int u, int v, int w)
{e[++num].next = h[u];e[num].to = v;e[num].dis = w;h[u] = num;
}void add_edge(int u, int v, int w)
{edge[++num_edge].next = head[u];edge[num_edge].to = v;edge[num_edge].dis = w;head[u] = num_edge;
}bool cmp(Ed x, Ed y) {return x.w < y.w;}void dfs(int x)
{vis[x] = 1, tag[x] = 1, tot++;for(int i = h[x]; i != 0; i = e[i].next)if(e[i].to != 1 && !vis[e[i].to]) dfs(e[i].to);
}int getFat(int x)
{if(x == fat[x]) return x;return fat[x] = getFat(fat[x]);
}void ddfs(int x, int fat)
{for(int i = head[x]; i != 0; i = edge[i].next)if(edge[i].to != fat){Max[edge[i].to] = max(Max[x], edge[i].dis);ddfs(edge[i].to, x);}
}void readIn()
{b["Park"] = 1, mp["Park"] = 1;for(int i = 1; i <= m; i++){string t1, t2;int u, v, w;cin >> t1 >> t2 >> w;if(!b[t1]) b[t1] = 1, mp[t1] = ++n;if(!b[t2]) b[t2] = 1, mp[t2] = ++n;u = mp[t1], v = mp[t2];ed[i].u = u, ed[i].v = v, ed[i].w = w;add(u, v, w), add(v, u, w);}cin >> S;
}int main()
{cin >> m;readIn();sort(ed + 1, ed + 1 + m, cmp);for(int i = 1; i <= n; i++) fat[i] = i;for(int i = 2; i <= n; i++)if(!vis[i]){T++, tot = g = 0;memset(tag, 0, sizeof(tag));dfs(i);for(int j = 1; j <= m; j++){if(tag[ed[j].u] && tag[ed[j].v] && getFat(ed[j].u) != getFat(ed[j].v)){fat[getFat(ed[j].u)] = getFat(ed[j].v);g++, ans += ed[j].w;add_edge(ed[j].u, ed[j].v, ed[j].w), add_edge(ed[j].v, ed[j].u, ed[j].w);}if(g == tot - 1) break;}int Min = inf, pos;for(int j = h[1]; j != 0; j = e[j].next)if(tag[e[j].to] && e[j].dis < Min) Min = e[j].dis, pos = e[j].to;ans += Min, fromOne[pos] = 1;add_edge(1, pos, Min), add_edge(pos, 1, Min);}Max[1] = -inf, ddfs(1, 0);for(int k = 1; k <= S - T; k++){int flag = 0, cost = -inf, pos;for(int i = h[1]; i != 0; i = e[i].next)if(!fromOne[e[i].to] && cost < (Max[e[i].to] - e[i].dis) && Max[e[i].to] - e[i].dis > 0)cost = Max[e[i].to] - e[i].dis, pos = e[i].to, flag = 1;if(!flag) break;ans -= cost, fromOne[pos] = 1;}cout << "Total miles driven: " << ans;return 0;
}

转载于:https://www.cnblogs.com/BigYellowDog/p/11386358.html

AcWing 野餐规划相关推荐

  1. acwing野餐规划

    搜索与回溯算法 #include<cmath> #include<cstdio> #include<cstring> #include<iostream> ...

  2. POJ1639 算法竞赛进阶指南 野餐规划

    题目描述 原题链接 一群小丑演员,以其出色的柔术表演,可以无限量的钻进同一辆汽车中,而闻名世界. 现在他们想要去公园玩耍,但是他们的经费非常紧缺. 他们将乘车前往公园,为了减少花费,他们决定选择一种合 ...

  3. 野餐规划(最小度限制生成树)

    题目 题目描述 一群小丑演员,以其出色的柔术表演,可以无限量的钻进同一辆汽车中,而闻名世界. 现在他们想要去公园玩耍,但是他们的经费非常紧缺. 他们将乘车前往公园,为了减少花费,他们决定选择一种合理的 ...

  4. [究极好题][最小生成树]野餐规划 AcWing347

    一群小丑演员,以其出色的柔术表演,可以无限量的钻进同一辆汽车中,而闻名世界. 现在他们想要去公园玩耍,但是他们的经费非常紧缺. 他们将乘车前往公园,为了减少花费,他们决定选择一种合理的乘车方式,可以使 ...

  5. ACWING347. 野餐规划(最小生成树)

    一群小丑演员,以其出色的柔术表演,可以无限量的钻进同一辆汽车中,而闻名世界. 现在他们想要去公园玩耍,但是他们的经费非常紧缺. 他们将乘车前往公园,为了减少花费,他们决定选择一种合理的乘车方式,可以使 ...

  6. 算法提高课-图论-负环-AcWing 1165. 单词环:spfa判正环、二分、01分数规划

    文章目录 题目分析 题目链接 题目分析 来源:acwing 分析: 如何建图? 这样建图.以样例举例.起点是前两个字母,终点是末尾两个字母,边权是字符串的长度. 我们求的是什么呢? 题目要求Σ边权Σ1 ...

  7. 算法提高课-图论-负环-AcWing 361. 观光奶牛:spfa判正环、负环、01分数规划、二分

    文章目录 题目分析 题目链接 题目分析 来源:acwing 分析: 题目要求ΣfiΣgi\frac{\Sigma{f_i}}{\Sigma{g_i}}Σgi​Σfi​​的最大值,这种问题称为01分数规 ...

  8. 解题报告:AcWing 1165. 单词环(01分数规划、hash、经验优化)

    本题的关键在于: 建图 01分数规划 本题的数据过大,如果直接spfa判断会TLE,因此我们使用经验优化,就是如果所有的点入队的次数过多,比如大于100000,那么我们直接认为它是存在正环的.(免去T ...

  9. acwing 1078. 旅游规划(求树直径上的点)

    题目链接 题意:给一个树,可能直径不唯一,求所有直径上的所有的点 思路: 这题刚开始以为可以两次bfs,第二次bfs的时候记录前驱暴力求解,结果tle了 = =.. 正确解法是,先用dp求直径,然后从 ...

最新文章

  1. Cissp-【第4章 通信与网络安全】-2021-3-12(446页-475页)
  2. java 同步方式 lock_Java的同步锁(Lock)
  3. 注解方式使用 Redis 缓存
  4. 《计算机网络》_学习笔记(一)
  5. python pandas n行求和,Python 的 Pandas 对矩阵的行进行求和
  6. asp.net很有用的字符串操作类
  7. Spark-Streaming
  8. worldwind java 教程,如何脱机使用World Wind Java SDK
  9. 分享几个有趣的Python小项目
  10. 【neo4j】docker容器化安装
  11. k3金蝶 java版本_金蝶KIS旗舰版和K3wise的不同
  12. Unity3d - 打飞碟
  13. 12帧跑步动画分解图_跑步动画原理讲解
  14. 【idea drools 执行20次失败中断崩溃】
  15. 数电设计--交通灯控制系统
  16. Boost.Asio 网络编程([译]Boost.Asio基本原理)
  17. Google chrome浏览器快捷方式
  18. 数字孪生的思考 05 - VAM/XR
  19. Word如何操作压缩图片?干货经验!怎么在Word中压缩图片?
  20. 将/etc/passwd文件的内容写入/tmp/passwd文件中

热门文章

  1. 巴比特 | 元宇宙每日必读:微软工业元宇宙应用中心落户昆山,首期规模10亿元的昆山高新区工业元宇宙产业基金成立...
  2. 项目独享IP,游戏工作室最佳的选择
  3. 剖析Hibernate主键生成几种常用方式
  4. 5分钟学会js上传图片校验图片格式、大小、尺寸宽高
  5. linux usb 子系统(二)- host driver
  6. 机器人科学家们,会带领我们进入美剧里描绘的「西部世界」么?
  7. android6.0电视优点,智能电视怎么样 智能电视优缺点解析【详解】
  8. 电脑怎么修改图片像素大小,快速批量处理方法
  9. 魏永明 “自主”操作系统
  10. 圆角边框(border-radius属性、border-radius使用规则)