题意:有 n 个圆环,其中有一些已经扣在一起了,现在要打开尽量少的环,使所有的环可以组成一条链。

析:刚开始看的时候,确实是不会啊。。。。现在有点思路,但是还是差一点,方法也不够好,最后还是参考了网上的题解,大神们的代码就是不一样,

但还是看了好久才看懂。首先是用二进制法进行暴力,因为 n 最大才是15,不会超时的,然后就是在暴力时判断打开这些环时,剩下的是不是还存在环,

如果存在那么不是不行的,然后再判断是不是有的环有两个分支以上,因为一个环如果成链那么最多只有两个分支,所以多于两个的也是不对的,最后,

还要判断打开的环是不是够用,什么意思?你想啊,如果打开的环只有2个,还需要连接的片段环有3个,那么正好,可以用这两个环把它们串起来,

但是片段环多于3个了,那么就不够了,总有几个是连不上的,所以还要满足这个条件,打开的环数要大于等于需要连接的片段减1.剩下的就是怎么判断

成环和分支大于两个了,先说怎么判断怎么计算分支大于两个,在暴力的时候,可以单独计算除了要打开的环并且和它连接的环的数量,如果多于2个,

那么就是分支大于2,再说怎么判断成环,很明显用dfs,从一个环出发,看看能不能再搜回来,如果能那么就是有环,最后是计算,打开了多少环,

这个最简单的是再单独暴力一下,找到一个就加1,最后算出来,当然可以用递归+位运算,就是一个数的二进制中1的数量,可以用按位与进行计算。

但我的代码效率不高,210ms,有点慢。。。

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring> using namespace std;
const int maxn = 15 + 5;
int n, num;
int G[maxn][maxn], vis[maxn]; bool branch(int s){//查找分支是多少
for(int i = 0; i < n; ++i){
if(s & (1<<i)) continue;//要打开的环
int cnt = 0;
for(int j = 0; j < n; ++j){
if(s & (1<<j)) continue;//这是要打开的环,不能计算
if(G[i][j]) ++cnt;//如果其他环与其相连接,就加1
}
if(cnt > 2) return true;//如果大于2,直接结束
}
return false;
} bool dfs(int s, int now, int fa){//now 表示当前的环是哪个,fa表示上一环是哪个,因为在搜索的时候不能搜自己
vis[now] = 1;
for(int i = 0; i < n; ++i){
if((s & (1<<i)) || !G[now][i] || i == fa) continue;//如果是打开的环或没有连接或者是自己,就跳过
if(vis[i] || dfs(s, i, now)) return true;//如果曾经访问过,也就是又找回来了。或者有环,直接返回
}
return false;
} bool circle(int s){//判断是不是有环
for(int i = 0; i < n; ++i){
if((s & (1<<i)) || vis[i]) continue;//是打开的环或者是已经访问的环
++num;
if(dfs(s, i, -1)) return true;//如果有环直接返回
}
return false;
} int cal(int s){ return s == 0 ? 0 : cal(s/2) + (s&1); }//计算要打开的环的数量 int solve(){
int ans = n-1;//最多就是打开n-1个
for(int i = 0; i < (1 << n); ++i){
memset(vis, 0, sizeof(vis));
num = 0;
if(branch(i) || circle(i)) continue;//如果有环或者是分支大于2个
if(cal(i) >= num-1) ans = min(ans, cal(i));//如果能够连起来,就更新ans
}
return ans;
} int main(){
// freopen("in.txt", "r", stdin);
int kase = 0;
while(scanf("%d", &n) == 1 && n){
int u, v;
memset(G, 0, sizeof(G));
while(scanf("%d %d", &u, &v) == 2 && u+v > 0){
G[u-1][v-1] = 1; G[v-1][u-1] = 1;
} printf("Set %d: Minimum links to open is %d\n", ++kase, solve());
}
return 0;
}

UVa 818Cutting Chains (暴力dfs+位运算+二进制法)的更多相关文章

  1. uva 10718 Bit Mask (位运算)

    uva 10718  Bit Mask  (位运算) Problem A Bit Mask Time Limit 1 Second In bit-wise expression, mask is a ...

  2. Codeforces Round #320 (Div. 2) [Bayan Thanks-Round] A. Raising Bacteria【位运算/二进制拆分/细胞繁殖,每天倍增】

    A. Raising Bacteria time limit per test 1 second memory limit per test 256 megabytes input standard ...

  3. UVA - 13022 Sheldon Numbers(位运算)

    UVA - 13022 Sheldon Numbers 二进制形式满足ABA,ABAB数的个数(A为一定长度的1,B为一定长度的0). 其实就是寻找在二进制中满足所有的1串具有相同的长度,所有的0串也 ...

  4. UVA 10718 Bit Mask 贪心+位运算

    题意:给出一个数N,下限L上限U,在[L,U]里面找一个整数,使得N|M最大,且让M最小. 很明显用贪心,用位运算搞了半天,样例过了后还是WA,没考虑清楚... 然后网上翻到了一个人家位运算一句话解决 ...

  5. luogu P2114 [NOI2014]起床困难综合症 位运算 二进制

    建议去uoj那里去测,数据比较强 位运算的题目,就得一位一位的分开考虑 然后枚举初始值的最高位是0 是1 的最终攻击 (二进制内)最高位是1肯定比次位是1次次位是1次次次位是1···的大吧,显然 然后 ...

  6. UVa 1590 IP网络(简单位运算)

    Description   Alex is administrator of IP networks. His clients have a bunch of individual IP addres ...

  7. 数独求解问题(DFS+位运算优化)

    In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For exa ...

  8. SRM331-CarolsSinging(暴力,位运算)

    Problem Statement When the Christmas dinner is over, it's time to sing carols. Unfortunately, not al ...

  9. UVa 1151 Buy or Build (最小生成树+二进制法暴力求解)

    题意:给定n个点,你的任务是让它们都连通.你可以新建一些边,费用等于两点距离的平方(当然越小越好),另外还有几种“套餐”,可以购买,你购买的话,那么有些边就可以连接起来, 每个“套餐”,也是要花费的, ...

随机推荐

  1. bzoj2750最短路计数

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2750 枚举每一个起点,通过该边的子树中有多少节点就知道本次它被经过几次了: 因为同一起点到该 ...

  2. Oracle表空间知识

    Oracle表空间知识 一,创建临时表空间 CREATE temporary TABLESPACE TEMP_PNLREPORT tempfile '/oradata2/ORCL/temp_pnlre ...

  3. 《Linux内核精髓:精通Linux内核必会的75个绝技》一HACK #14 虚拟存储子系统的调整

    HACK #14 虚拟存储子系统的调整 本节介绍如何使用/proc进行虚拟存储子系统的调整.虚拟空间存储方式在Linux上向应用程序分配内存时,是通过以页面为单位的虚拟存储方式进行的.采用虚拟存储方式 ...

  4. 线程等待 Join()方法

    Join()方法是让一个线程等待另一个线程的完成 下面看个例子: package project11; public class TestJoin extends Thread { public vo ...

  5. Eclipse使用技巧汇总

    Eclipse中设置作者日期等Java注释模板 参考网址:https://jingyan.baidu.com/article/1612d500856cb1e20e1eeed5.html

  6. Apache Kylin本地启动

    首先:kylin是一种Online Analytics Platform.    kylin 在Apache的首页是http://kylin.apache.org/cn/.    kylin git代 ...

  7. django-url命名空间+反查

    from django.conf.urls import url, include urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^h ...

  8. windows下使用 ApiGen 生成php项目的开发文档

    之前使用 PHPDocument 生成过开发文档,但是界面看着不爽,遂尝试了 ApiGen 生成,不得不说界面看着舒服多了,下面说说安装和使用的方法. ApiGen官网: http://www.api ...

  9. FDQuery sqlserver 临时表

    用FDQuery执行创建临时表,查不到临时表,用ADOQuery和BDEQuery均正常,比较发现用ADOQuery执行的时候只有SQL没有调用sql的系统存储过程sp_prepexec. 是fdqu ...

  10. 人脸识别-<转>

    人脸检测库libfacedetection介绍 libfacedetection是于仕琪老师放到GitHub上的二进制库,没有源码,它的License是MIT,可以商用.目前只提供了windows 3 ...