UVa 818:Cutting Chains(暴力)
2015-09-15 10:03
561 查看
题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=842&page=show_problem&problem=759
题意:有n(n \le 15)个圆环,其中有一些已经扣在了一起。现在需要打开尽量少的圆环,使得所有的圆环可以组成一条链(当然,所有打开的圆环最后都要再次闭合)。例如,有5个圆环,1-2,2-3,4-5,则需要打开一个圆环,如圆环4,然后用它穿过圆环3和圆环5后再次闭合圆环4,就可以形成一条链:1-2-3-4-5。(本段摘自《算法竞赛入门经典(第2版)》)
分析:
用二进制枚举断开的圆环数,分析剩下的圆环是否有分支大于2的或者存在环的,如果有则不符合,如果没有,看断开的圆环数+1是否大于等于剩下的圆环组数,如果符合则找到一个解,最后取解的最小值即可。
代码:
题意:有n(n \le 15)个圆环,其中有一些已经扣在了一起。现在需要打开尽量少的圆环,使得所有的圆环可以组成一条链(当然,所有打开的圆环最后都要再次闭合)。例如,有5个圆环,1-2,2-3,4-5,则需要打开一个圆环,如圆环4,然后用它穿过圆环3和圆环5后再次闭合圆环4,就可以形成一条链:1-2-3-4-5。(本段摘自《算法竞赛入门经典(第2版)》)
分析:
用二进制枚举断开的圆环数,分析剩下的圆环是否有分支大于2的或者存在环的,如果有则不符合,如果没有,看断开的圆环数+1是否大于等于剩下的圆环组数,如果符合则找到一个解,最后取解的最小值即可。
代码:
#include <iostream> #include <algorithm> #include <fstream> #include <string> #include <cstring> #include <vector> #include <queue> #include <cmath> #include <cctype> #include <stack> #include <set> using namespace std; const int maxn = 15 + 5, INF = 10; int n, x, y, ans, num, C; int m[maxn][maxn], v[maxn]; bool two(int s) { for (int i = 0; i < n; ++i) { int cnt = 0; for (int j = 0; j < n; ++j) if (m[i][j] && !(s & (1 << i)) && !(s & (1 << j))) { ++cnt; if (cnt == 3) return true; } } return false; } bool DFS(int x, int f, int s) { v[x] = 1; for (int i = 0; i < n; ++i) if (m[x][i] && !(s & (1 << i))) { if (!v[i]) { if (DFS(i, x, s)) return true; } else if (i != f) return true; } return false; } bool circle(int s) { memset(v, 0, sizeof(v)); for (int i = 0; i < n; ++i) if (!v[i] && !(s & (1 << i))) { if (DFS(i, -1, s)) return true; ++num; } return false; } int calc(int s) { int res = 0; for (int i = 0; i < n; ++i) { if (s & 1) ++res; s >>= 1; } return res; } int main() { while (~scanf("%d", &n), n) { ans = n; memset(m, 0, sizeof(m)); while (scanf("%d%d", &x, &y), x != -1 && y != -1) { m[x - 1][y - 1] = 1; m[y - 1][x - 1] = 1; } for (int i = 0; i < (1 << n); ++i) { num = 0; if (two(i) || circle(i)) continue; int tmp = calc(i); if (num - 1 <= tmp) ans = min(ans, tmp); } printf("Set %d: Minimum links to open is %d\n", ++C, ans); } return 0; }
相关文章推荐
- ofbiz email-send
- Unit of work, Transactions and Grails
- max-min fairness 最大最小公平算法
- LeetCode-Contains Duplicate
- 系统调用跟我学之wait, waitpid函数
- 启动2015世界人工智能系统智商排名,检测人工智能是否超越人类
- 算法系列--Climbing Stairs
- http://blog.csdn.net/u011975949/article/details/46868373
- 报表XML导出rtf格式,结果在浏览器中打开XML文件。下载rtf文件打开后出现Authentication failed 问题
- rails
- stackstack pillar and grains
- leetcode 220 Contains Duplicate III
- linux 中/proc 详解 http://blog.csdn.net/kevinx_xu/article/details/8178746
- main函数可否被递归调用
- poj1363Rails(栈模拟)
- jedis高版本,JedisPoolConfig,maxActive属性,maxWait,配置maxActive,maxTotal,maxWaitMillis
- AIX常用
- POJ1681 Painter's Problem【高斯消元法】
- Climbing Stairs
- 配置sendmail转发邮件