题意:有 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. zipkin:和springcloud集成过程记录

    发现全是springcloudapp的名称,然后是springcloudapp(http://localhost:8080/hello/tom)工程单独调用并没有通知zipkin: 原来是因为rest ...

  2. ffmpeg V4L2_BUF_FLAG_ERROR的解决方法

    利用ffmpeg进行视频采集时经常出现“V4L2_BUF_FLAG_ERROR”的错误,并不再进行下帧的采集.通过借鉴下面的方法,对ffmpeg3.0.7版本进行补丁,能解决此类问题. 当某帧出错后, ...

  3. Ubuntu14.04下Sublime Text 3解决无法输入中文

    在Ubuntu 14.04中安装了SublimeText 3之后发现既然不支持输入中文,于是在网上搜罗一下,发现很多人遇到了同样的问题,但是解决办法大该就只有一个.下面根据自身的安装及解决办法总结如下 ...

  4. C#两个日期范围内的间隔

    http://www.cnblogs.com/love_study/archive/2011/04/02/2003045.html 引用地址 1 /// <summary> /// 计算日 ...

  5. 【POJ】1935 Journey(树形dp)

    题目 传送门:QWQ 分析 凉凉. 答案是所有要经过的点到根所经过的边权和减去最大的边权. 代码 vector好慢啊 #include <cstdio> #include <vect ...

  6. Carrying per-request context using the HttpRequestMessage.Properties

    In a Web API application, I use Castle Windsor to supply services configured with PerWebRequest life ...

  7. leetcode28

    public class Solution { public int StrStr(string haystack, string needle) { return haystack.IndexOf( ...

  8. html 1.0 鼠标放上去会亮 onmouseover onmouseout 以及this标签的使用

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. 6 MySQL--表--完整性约束

    参考:https://www.cnblogs.com/alice-bj/p/8824693.html 完整性约束: http://www.cnblogs.com/linhaifeng/articles ...

  10. U3D 如何计算一个UI四个角的绝对坐标

      //方式一,使用API获取 var rtrans = gameObject.GetComponent<RectTransform>(); Vector3[] worldcorners ...