UVA-818 dfs + 位运算
暴力枚举一些圆环,将这些圆环解开,看能否成为单链。判断单链的三个条件:
- 除了这些删除的圆环之外,其他圆环还连接着的圆环不能超过两个。
- 剩下的环没有连成圈。
- 剩下的圆环共分成m堆,每堆之间无连接,m必须小于等于解开的圆环数+1。
最多有15个环,可以用二进制保存。
AC代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
using namespace std;
#define pos(x) (1 << ((x) - 1))
const int maxn = 20;
int g[maxn], vis[maxn], d[maxn];
int n;
int bit(int x) {
int cnt = 0;
while(x > 0) {
if(x & 1) ++cnt;
x >>= 1;
}
return cnt;
}
bool dfs(int u, int pre){
vis[u] = -1;
int m = g[u];
for(int i = 1; i <= n; ++i){
if(d[i] || i == pre || !(pos(i) & m)) continue;
if(vis[i] == -1) return false;
if(!vis[i] && !dfs(i, u)) return false;
}
vis[u] = 1;
return true;
}
bool solve(int p){
memset(vis, 0, sizeof(vis));
memset(d, 0, sizeof(d));
for(int i = 1; i <= n; ++i){
if(pos(i) & p) d[i] = 1;
}
for(int i = 1; i <= n; ++i) {
if(d[i]) continue;
int x = 0;
for(int j = 1; j <= n; ++j){
if(!d[j] && pos(j) & g[i]) ++x;
}
if(x > 2) return false;
}
int cnt = 0; //联通块数量
for(int i = 1; i <= n; ++i){
if(vis[i] || d[i]) continue;
if(!dfs(i, -1)) return false; //有环
++cnt;
}
if(cnt > bit(p) + 1) return false; //大于独立的圆环数,无法连接
return true;
}
int main() {
int kase = 0;
while(scanf("%d", &n) == 1 && n){
int a, b;
memset(g, 0, sizeof(g));
while(1) {
scanf("%d%d", &a, &b);
if(a == -1 && b == -1) break;
g[a] |= (1 << (b - 1)); //a can reach b
g[b] |= (1 << (a - 1)); //b can reach a
}
int total = 1 << n;
int ans = 1 << 30;
for(int i = 0; i < total; ++i) {
if(bit(i) >= ans) continue;
if(solve(i)) {
ans =min(ans, bit(i));
}
}
printf("Set %d: Minimum links to open is %d\n", ++kase, ans);
}
return 0;
}
如有不当之处欢迎指出!
UVA-818 dfs + 位运算的更多相关文章
- uva 818 (位运算 + 判环)
Cutting Chains What a find! Anna Locke has just bought several links of chain some of which may be ...
- UVa 818Cutting Chains (暴力dfs+位运算+二进制法)
题意:有 n 个圆环,其中有一些已经扣在一起了,现在要打开尽量少的环,使所有的环可以组成一条链. 析:刚开始看的时候,确实是不会啊....现在有点思路,但是还是差一点,方法也不够好,最后还是参考了网上 ...
- 数独求解问题(DFS+位运算优化)
In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For exa ...
- UVA 690 PipelineScheduling 位运算+dfs+剪枝
一开始最容易想到间隔最多为n,但是结点还是太多了,需要优化. 预处理:预判一下并保存下一个可以放的位置距离之前的距离.这样可以减少很多判断. 最优化剪枝:如果当前长度+剩下没放的程序*最短间隔如果大于 ...
- POJ 1164 城堡问题【DFS/位运算/种子填充法/染色法】
1 2 3 4 5 6 7 ############################# 1 # | # | # | | # #####---#####---#---#####---# 2 # # | ...
- UVA 11464 暴力+位运算 ***
题意:给你一个 n * n 的 01 矩阵,现在你的任务是将这个矩阵中尽量少的 0 转化为 1 ,使得每个数的上下左右四个相邻的数加起来是偶数.求最少的转化个数. 新风格代码 lrj书上说的很清楚了, ...
- uva 10718 Bit Mask (位运算)
uva 10718 Bit Mask (位运算) Problem A Bit Mask Time Limit 1 Second In bit-wise expression, mask is a ...
- 【位运算DFS/DLX】【HDU1426】【数独】
题意:标准的一道数独题 DFS做法: 将横纵九宫格里的数字用位运算状态压缩,且可以通过逻辑或来确定总共有哪些数字被选择了,很方便也很快,代码如下 #include <cstdio> #in ...
- UVA 10718 Bit Mask 贪心+位运算
题意:给出一个数N,下限L上限U,在[L,U]里面找一个整数,使得N|M最大,且让M最小. 很明显用贪心,用位运算搞了半天,样例过了后还是WA,没考虑清楚... 然后网上翻到了一个人家位运算一句话解决 ...
随机推荐
- ImmutableMap
不可变集合,为什么使用它呢?线程安全\更有效的利用内存\可作为常量 ImmutableMap.<String, Object> builder().put("yananList& ...
- MS SQL 监控数据/日志文件增长
前几天,在所有数据库服务器部署了监控磁盘空间的存储过程和作业后(MS SQL 监控磁盘空间告警),今天突然收到了两封告警邮件,好吧,存储规划是一方面,但是,是不是要分析一下是什么原因造成磁盘空 ...
- 如何用Python爬虫实现百度图片自动下载?
Github:https://github.com/nnngu/LearningNotes 制作爬虫的步骤 制作一个爬虫一般分以下几个步骤: 分析需求 分析网页源代码,配合开发者工具 编写正则表达式或 ...
- Shell 批量复制文件名相近的文件到指定文件名中
问题: 目录结构如下: test/ 2001.01.01/ 2001.02.02/ 2001.03.02/ 2001.01.03/ 2001.02.04/ 2001.03.05/ 2 ...
- ferror,perror,cleaner
1.ferror 函数原型: int ferror(FILE *fp) 功能:测试文件是否出现错误 返回值:未出错是0:出错为非0. 每次调用文件输入输出函数,均产生一个新的ferror函数值 fop ...
- cat写入数据
1.cat可以利用两个>>把内容追加到文件中 cat >>oldboy.txt<<EOF >1 >2 >EOF 会在文件中加入EOF中间的数据.E ...
- jsp中实现点击文件名称完成下载
1.文件名称添加点击事件 <a href="javascript:void(0);" id="wjm" onclick="wjxz();&quo ...
- 简易发号SQL,可用于生成指定前缀自增序列,如订单号,生成优惠券码等
需求1:订单号要求唯一.长度不太长.自增.但不能通过早上订单号和晚上订单号相减推算出平台大概一天的单量 需求2:要求生成10w张优惠券,要求券码唯一.不能太长,不能轻易猜测出其他券码 根据这些需求提供 ...
- A 洛谷 P3601 签到题 [欧拉函数 质因子分解]
题目背景 这是一道签到题! 建议做题之前仔细阅读数据范围! 题目描述 我们定义一个函数:qiandao(x)为小于等于x的数中与x不互质的数的个数. 这题作为签到题,给出l和r,要求求. 输入输出格式 ...
- ionic2+Angular 组件(多个组件)浅谈
第一步,新建组件: ionic g component product-img-list 命令执行成功之后项目中生成的文件: 第二步:生成文件解析: ①product-img-list.ts impo ...