[暑假集训Day2T3]团建活动
个人认为这周题中较难的一道。
题意大概为:给定一张N个点M条边的无向图,求出无向图的一棵最小生成树,满足一号节点的度数不超过给定的整数K。保证 N <= 20
首先用map存取节点,之后抛去1号节点,求每一个联通分量的MST,就得到了一个局部最优解,设p为联通块的个数,接下来从每一个联通分量中找一个离1号节点距离最近的点,连接其与1号节点的边,就得到了一棵1号节点度数为p的生成树,之后逐渐放宽限制,枚举最终答案的度数,每次从1号节点往其他点连边,会形成一个环,求出该点到1路径上形成的环中边权最大值,之后把这个最大值剪断,将1号节点和该点连边。直到减小不了权值为止
下面给出标程(Author:????)
- #include <map>
- #include <cstdio>
- #include <string>
- #include <vector>
- #include <cstring>
- #include <iostream>
- #include <algorithm>
- using namespace std;
- const int N = , INF = 0x3f3f3f3f;
- struct E {
- int x, y, z;
- bool operator < (const E w) const
- {
- return z < w.z;
- }
- }f[N];
- int n, k, tot, ans, a[N][N], fa[N], d[N], v[N];
- map<string, int> m;
- vector<E> e;
- bool b[N][N];
- int get(int x) {
- if (x == fa[x]) return x;
- return fa[x] = get(fa[x]);
- }
- // dfs(1,-1)
- void dfs(int x, int o) {
- for (int i = ; i <= tot; i++) {
- if (i == o || b[x][i]==) continue;
- if (f[i].z == -) {
- if (f[x].z > a[x][i]) f[i] = f[x];
- else {
- f[i].x = x;
- f[i].y = i;
- f[i].z = a[x][i];
- }
- }
- dfs(i, x);
- }
- }
- int main() {
- cin >> n;
- memset(a, 0x3f, sizeof(a));
- memset(d, 0x3f, sizeof(d));
- m["Park"] = tot = ;
- for (int i = ; i < N; i++) fa[i] = i;
- for (int i = ; i <= n; i++) {
- E w;
- string s1, s2;
- cin >> s1 >> s2 >> w.z;
- w.x = m[s1] ? m[s1] : (m[s1] = ++tot);
- w.y = m[s2] ? m[s2] : (m[s2] = ++tot);
- e.push_back(w);
- a[w.x][w.y] = a[w.y][w.x] = w.z;
- }
- cin >> k;
- sort(e.begin(), e.end());
- for (unsigned int i = ; i < e.size(); i++) {
- if (e[i].x == || e[i].y == ) continue;
- int rtx = get(e[i].x), rty = get(e[i].y);
- if (rtx != rty) {
- fa[rtx] = rty;
- b[e[i].x][e[i].y] = b[e[i].y][e[i].x] = ;
- ans += e[i].z;
- }
- }
- for (int i = ; i <= tot; i++)
- if (a[][i] != INF) {
- int rt = get(i);
- if (d[rt] > a[][i])
- d[rt] = a[][v[rt]=i]; // 记下每个父节点对应的边缘点以及边缘点和1号点的权值
- }
- for (int i = ; i <= tot; i++)
- if (d[i] != INF) {
- --k;
- b[][v[i]] = b[v[i]][] = ;
- ans += a[][v[i]];
- }
- //cout<<k<<endl;
- while (k--) {
- memset(f, -, sizeof(f));
- f[].z = -INF;
- for (int i = ; i <= tot; i++)
- if (b[][i]) f[i].z = -INF;
- dfs(, -);
- int o, w = -INF;
- for (int i = ; i <= tot; i++)
- if (w < f[i].z - a[][i])
- w = f[i].z - a[][o=i];
- if (w <= ) break;
- //cout<<o<<endl;
- b[][o] = b[o][] = ;
- b[f[o].x][f[o].y] = b[f[o].y][f[o].x] = ;
- ans -= w;
- }
- printf("Total miles driven: %d\n", ans);
- return ;
- }
[暑假集训Day2T3]团建活动的更多相关文章
- 【团购活动】接口最全最好用的S5PV210开发板Sate210-F 开发板开始团购活动了,一起学习linux!
接口最全最好用的S5PV210开发板Sate210-F 开发板开始团购活动了,一起学习linux!http://bbs.eeworld.com.cn/forum.php?mod=viewthread& ...
- 2015UESTC 暑假集训总结
day1: 考微观经济学去了…… day2: 一开始就看了看一道题目最短的B题,拍了半小时交了上去wa了 感觉自己一定是自己想错了,于是去拍大家都过的A题,十分钟拍完交上去就A了 然后B题写了一发暴力 ...
- STL 入门 (17 暑假集训第一周)
快速全排列的函数 头文件<algorithm> next_permutation(a,a+n) ---------------------------------------------- ...
- 暑假集训Day2 互不侵犯(状压dp)
这又是个状压dp (大型自闭现场) 题目大意: 在N*N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. ...
- 暑假集训Day1 整数划分
题目大意: 如何把一个正整数N(N长度<20)划分为M(M>=1)个部分,使这M个部分的乘积最大.N.M从键盘输入,输出最大值及一种划分方式. 输入格式: 第一行一个正整数T(T<= ...
- 2013ACM暑假集训总结-致将走上大三征途的我
回想起这个暑假,从开始与雄鹰一起的纠结要不要进集训队,与吉吉博博组队参加地大邀请赛,害怕进不了集训队.当时激励我月份开始接触的,记得当时在弄运动会来着,然后就问了雄鹰一些输入输出的东西,怀着满心的期待 ...
- [补档]暑假集训D6总结
考试 不是爆零,胜似爆零= = 三道题,就拿了20分,根本没法玩好吧= = 本来以为打了道正解,打了道暴力,加上个特判分,应该不会死的太惨,然而--为啥我只有特判分啊- - 真的是惨. 讲完题觉得题是 ...
- [补档]暑假集训D5总结
%dalao 今天又有dalao来讲课,讲的是网络流 网络流--从入门到放弃:7-29dalao讲课笔记--https://hzoi-mafia.github.io/2017/07/29/27/ ...
- [补档]暑假集训D1总结
归来 今天就这样回来了,虽然心里极其不想回来(暑假!@#的只有一天啊喂),但还是回来了,没办法,虽然不喜欢这个地方,但是机房却也是少数能给我安慰的地方,心再累,也没有办法了,不如好好集训= = %da ...
随机推荐
- python 简易小爬虫
此脚本用于爬站点的下载链接,最终输出到txt文档中. 如果是没有防盗链设置的站点,也可以使用脚本中的下载函数尝试直接下载. 本脚本是为了短期特定目标设计的,如果使用它爬其它特征的资源链接需自行修改配置 ...
- 380-Xilinx Kintex UltraScale FPGA KCU1500 Acceleration Development Kit
Xilinx Kintex UltraScale FPGA KCU1500 Acceleration Development Kit Product Description The Kintex® U ...
- linux使用v 2ray
一.安装配置服务端程序 是时候使用 了,因为相对安全,使用方法很简单,使用root权限执行以下命令即可 $ sudo -i 一顿安装后如图 输入 命令可以查看链接,然后在客户端使用这个链接就能配置好了 ...
- .OnCommand mfc
.OnCommand是响应WM_COMMAND消息的,一般是响应控件和菜单的命令消息时使用. 如果 WM_COMMAND 来自控件的话 lParam 就是发送这个 WM_COMMAND 消息的控件的句 ...
- 函数柯里化(Currying)小实践
什么是函数柯里化 在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术.这个技术由 Ch ...
- AJAX——理解XMLHttpRequest对象
AJAX大家已经都知道了,XMLHttpRequest对象则是AJAX的核心.这篇博客重点总结一下这个对象的使用. XMLHttpRequest对象的属性和方法: 属性 说明 readyState 表 ...
- Redis-缓存击穿/穿透/雪崩
缓存击穿/穿透/雪崩 Intro 使用缓存需要了解几个缓存问题,缓存击穿.缓存穿透以及缓存雪崩,需要了解它们产生的原因以及怎么避免,尤其是当你打算设计自己的缓存框架的时候需要考虑如何处理这些问题. 缓 ...
- 【leetcode】877. Stone Game
题目如下: Alex and Lee play a game with piles of stones. There are an even number of piles arranged in ...
- 06 IntelliJ IDEA构建多模块项目
- BZOJ 1112: [POI2008]砖块Klo Splay + 性质分析
Code: #include<bits/stdc++.h> using namespace std; #define setIO(s) freopen(s".in",& ...