题意:给你n个点,点带权,任意两点之间的边权是它们的点权的异或值中“1”的个数,问你该图的最小生成树。

看似是个完全图,实际上有很多边是废的。类似……卡诺图的思想?从读入的点出发BFS,每次只到改变它的任意一位所能到达的点(不论是否读入)。

记录每个点是从哪个读入点BFS过来的,当第二次访问某个点的时候,就将它的两个源头(一次是第一次的时候标记的,一次是第二次过来的)连一条边。

这样最多连m(位数)*n条边,实际上比这个值更小。

这种做法可以将很多显然不会出现在最小生成树里的边排除掉。

opencup的标程:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
// O(kn) #include <bits/stdc++.h> using namespace std; struct FAU {
vector <int> p, r; FAU(int n): p(n,-1), r(n,0) {} int find(int x) {
if (p[x] == -1) return x;
return p[x] = find(p[x]);
} void join(int x, int y) {
x = find(x); y = find(y);
if (x == y) return ; if (r[x] > r[y]) p[y] = x;
else p[x] = y; if (r[x] == r[y]) ++r[y];
}
}; int readBinary() {
string s;
cin >> s; int result = 0;
for (char c : s) {
result = 2 * result + ((c == 'L') ? 1 : 0);
} return result;
} void solveTestcase() {
int k, n;
cin >> k >> n; const int N = 1 << k; vector <int> dist(N, -1), from(N);
queue <int> q; for (int i = 0; i < n; i++) {
int val = readBinary(); dist[val] = 0;
from[val] = i; q.push(val);
} vector <vector <pair<int,int>>> edges(k+1); while (!q.empty()) {
int v = q.front(); q.pop(); for (int bit = 0; bit < k; bit++) {
int u = v ^ (1 << bit); if (dist[u] == -1) {
dist[u] = 1 + dist[v];
from[u] = from[v]; q.push(u);
} else if (from[u] != from[v]) {
int len = dist[u] + dist[v] + 1; if (len <= k) {
edges[len].push_back({from[u], from[v]});
}
}
}
} FAU fau(n);
int ans = 0; for (int len = 1; len <= k; len++) for (auto &edge : edges[len]) {
if (fau.find(edge.first) != fau.find(edge.second)) {
ans += len;
fau.join(edge.first, edge.second);
}
} cout << ans << '\n';
} int main() {
ios_base::sync_with_stdio(false); int z;
cin >> z; while (z--) {
solveTestcase();
} return 0;
}

【BFS】【最小生成树】Petrozavodsk Winter Training Camp 2018 Day 1: Jagiellonian U Contest, Tuesday, January 30, 2018 Problem G. We Need More Managers!的更多相关文章

  1. 【模拟退火】Petrozavodsk Winter Training Camp 2017 Day 1: Jagiellonian U Contest, Monday, January 30, 2017 Problem F. Factory

    让你在平面上取一个点,使得其到给定的所有点的距离和最小. 就是“费马点”. 模拟退火……日后学习一下,这是从网上扒的,先存下. #include<iostream> #include< ...

  2. 【动态规划】【二分】Petrozavodsk Winter Training Camp 2017 Day 1: Jagiellonian U Contest, Monday, January 30, 2017 Problem B. Dissertation

    题意: 给定S1串,长度100w,S2串,长度1k.问它俩的LCS. f(i,j)表示S2串前i个字符,LCS为j时,最少需要的S1串的前缀长度.转移的时候,枚举下一个字符在S1的位置即可.(可以预处 ...

  3. 【二分】Petrozavodsk Winter Training Camp 2017 Day 1: Jagiellonian U Contest, Monday, January 30, 2017 Problem A. The Catcher in the Rye

    一个区域,垂直分成三块,每块有一个速度限制,问你从左下角跑到右上角的最短时间. 将区域看作三块折射率不同的介质,可以证明,按照光路跑时间最短. 于是可以二分第一个入射角,此时可以推出射到最右侧边界上的 ...

  4. 【取对数】【哈希】Petrozavodsk Winter Training Camp 2018 Day 1: Jagiellonian U Contest, Tuesday, January 30, 2018 Problem J. Bobby Tables

    题意:给你一个大整数X的素因子分解形式,每个因子不超过m.问你能否找到两个数n,k,k<=n<=m,使得C(n,k)=X. 不妨取对数,把乘法转换成加法.枚举n,然后去找最大的k(< ...

  5. 【状压dp】Petrozavodsk Winter Training Camp 2018 Day 1: Jagiellonian U Contest, Tuesday, January 30, 2018 Problem E. Guessing Game

    题意:给你n个两两不同的零一串,Alice在其中选定一个,Bob去猜,每次询问某一位是0 or 1.问你最坏情况下最少要猜几次. f(22...2)表示当前状态的最小步数,2表示这位没确定,1表示确定 ...

  6. 【推导】【单调性】Petrozavodsk Winter Training Camp 2018 Day 1: Jagiellonian U Contest, Tuesday, January 30, 2018 Problem B. Tribute

    题意:有n个数,除了空集外,它们会形成2^n-1个子集,给你这些子集的和的结果,让你还原原来的n个数. 假设原数是3 5 16, 那么它们形成3 5 8 16 19 21 24, 那么第一轮取出开头的 ...

  7. 【线性基】Petrozavodsk Winter Training Camp 2018 Day 1: Jagiellonian U Contest, Tuesday, January 30, 2018 Problem A. XOR

    题意:给你一些数,问你是否能够将它们划分成两个集合,使得这两个集合的异或和之差的绝对值最小. 设所有数的异或和为S,集合A的异或和为A. 首先,S的0的位对答案不造成影响. S的最高位1,所对应的A的 ...

  8. 【推导】【构造】Petrozavodsk Summer Training Camp 2015 Day 2: Xudyh (TooSimple) Contest, Saturday, August 22, 2015 Problem G. Travelling Salesman Problem

    一个矩阵,每个位置有一个非负整数,一个人从左上走到右下,不能走重复的格子,问得到的最大权值. 当长宽不都为偶数时,必然能走遍所有格子,横着从左到右,从右到左(或是竖着走)走完即可. 当长宽都是偶数时, ...

  9. Petrozavodsk Winter Training Camp 2018

    Petrozavodsk Winter Training Camp 2018 Problem A. Mines 题目描述:有\(n\)个炸弹放在\(x\)轴上,第\(i\)个位置为\(p_i\),爆炸 ...

随机推荐

  1. Spring4笔记7--AspectJ 对 AOP 的实现

    AspectJ 对 AOP 的实现: 对于 AOP 这种编程思想,很多框架都进行了实现.Spring 就是其中之一,可以完成面向切面编程.然而,AspectJ 也实现了 AOP 的功能,且其实现方式更 ...

  2. Python time()方法

    from:http://www.runoob.com/python/att-time-time.html 描述 Python time time() 返回当前时间的时间戳(1970纪元后经过的浮点秒数 ...

  3. [MySQL FAQ]系列 — EXPLAIN结果中哪些信息要引起关注

    我们使用EXPLAIN解析SQL执行计划时,如果有下面几种情况,就需要特别关注下了: 首先看下 type 这列的结果,如果有类型是 ALL 时,表示预计会进行全表扫描(full table scan) ...

  4. Tomcat安装与优化

    Tomcat安装与优化 1.安装jdk环境 最新的JDK下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downlo ...

  5. 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 Coin 概率+矩阵快速幂

    题目链接: https://nanti.jisuanke.com/t/17115 题意: 询问硬币K次,正面朝上次数为偶数. 思路: dp[i][0] = 下* dp[i-1][0] + 上*dp[i ...

  6. mysql高可用架构 -> MHA主从复制-03

    GTID复制技术说明 GTID的全称为 global transaction identifier ,可以翻译为全局事务标示符,GTID在原始master上的事务提交时被创建.GTID需要在全局的主- ...

  7. mysql高可用架构 -> MHA简介-01

    作者简介 松信嘉範:MySQL/Linux专家2001年索尼公司入职2001年开始使用oracle2004年开始使用MySQL2006年9月-2010年8月MySQL从事顾问2010年-2012年 D ...

  8. Shell脚本系列教程二: 开始Shell编程

    Shell脚本系列教程二: 开始Shell编程 2.1 如何写shell script? (1) 最常用的是使用vi或者mcedit来编写shell脚本, 但是你也可以使用任何你喜欢的编辑器; (2) ...

  9. 【CF767C】Garland

    传送门啦 分析: 这个题我是看着翻译做的,感觉不是很难,很普通的一个树形dp 题目大意: 在一棵树上分离出三个子树,使这三个子树的点权和相等. 明确题目意思这个题就简单多了吧. 我们会发现每一棵子树的 ...

  10. Linux学习笔记:cat、tac、more、less、head、tail查看文件内容

    Linux下查看文件内容可以通过以下命令: cat tac more less head tail nl tailf 1.cat 由第一行开始显示内容,并将所有内容输出.当文件过大时,使用cat查看不 ...