UVA 818 Cutting Chains
2016-04-26 08:10
387 查看
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=35523
题意:有n个圆环,其中有一些已经扣在一起。现在需要打开尽量少的圆环,使得所有圆环可以组成一条链(所有打开的圆环最后都要再次闭合)。例:1-2 2-3 4-5,则需要打开圆环4,用它穿过3和5后再次闭合。
思路:由于n不大,我们可以枚举所有打开的情况去检查是否合法,然后取答案最小的值。我们打开了k个圆环后,先除去这些圆环以及与它相关的所有边,剩下的圆环会变为p个部分。要满足每个部分都是一条链,且k>=p-1时才合法。判断一个部分是不是一条链,首先不能有度数超过2的点,其次度数为2的点不能超过这个部分总点数-2(去掉两头度数为1的点)。
题意:有n个圆环,其中有一些已经扣在一起。现在需要打开尽量少的圆环,使得所有圆环可以组成一条链(所有打开的圆环最后都要再次闭合)。例:1-2 2-3 4-5,则需要打开圆环4,用它穿过3和5后再次闭合。
思路:由于n不大,我们可以枚举所有打开的情况去检查是否合法,然后取答案最小的值。我们打开了k个圆环后,先除去这些圆环以及与它相关的所有边,剩下的圆环会变为p个部分。要满足每个部分都是一条链,且k>=p-1时才合法。判断一个部分是不是一条链,首先不能有度数超过2的点,其次度数为2的点不能超过这个部分总点数-2(去掉两头度数为1的点)。
#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <cstdlib> #include <iostream> #include <algorithm> #include <stack> #include <map> #include <set> #include <vector> #include <sstream> #include <queue> #include <utility> using namespace std; #define rep(i,j,k) for (int i=j;i<=k;i++) #define Rrep(i,j,k) for (int i=j;i>=k;i--) #define Clean(x,y) memset(x,y,sizeof(x)) #define LL long long #define ULL unsigned long long #define inf 0x7fffffff #define mod %100000007 int n; int a,b; //vector<int> edge[20]; int flag[20]; int num[1<<15]; bool f[20][20]; bool dfs(int x , int &l2 , int &tot) // -1 当前集合且访问过 0已经访问过的集合里 1未访问 { tot++; flag[x] = -1; //if ( edge[x].size() == 0 ) return true; int du = 0; bool can = true; //for( int i = 0; i < int(edge[x].size()); i++ ) rep(i,1,n) { if( i == x ) continue; if ( f[x][i] && flag[i] ) du++; if ( f[x][i] && flag[i] == 1 ) can = can && dfs(i,l2,tot); } if ( du > 2 || !can ) return false; if ( du == 2 ) l2++; flag[x] = 0; return true; } bool check(int state) { rep(i,1,n) flag[i] = 1; rep(i,1,n) if ( state & 1<<(i-1) ) flag[i] = 0; int p = 0; rep(i,1,n) if ( flag[i] == 1 ) { p++; int l2 = 0; int tot = 0; if ( !dfs(i,l2,tot) ) return false; if ( l2 && l2 > tot-2 ) return false; } return p-1<=num[state]; } int main() { Clean(num,0); rep(i,0,(1<<15)-1) { int x = 0; rep(j,0,14) if ( i & (1<<j) ) x++; num[i] = x; } int kase = 0; while( ~scanf("%d",&n) ) { if ( !n ) break; //rep(i,1,n) edge[i].clear(); Clean(f,false); while( scanf("%d%d",&a,&b) ) { if ( a == -1 && b == -1 ) break; f[a][b] = true; f[b][a] = true; //edge[a].push_back(b); //edge[b].push_back(a); } int ans = n; int uplim = 1<<n; rep(i,0,uplim-1) { if ( num[i] >= ans ) continue; if ( check(i) ) ans = min(ans , num[i] ); } printf("Set %d: Minimum links to open is %d\n",++kase,ans); } return 0; }
相关文章推荐
- postmain 导致浏览器两次请求
- LintCode: Paint House II
- (整理)IIS 7 503 "service unavailable" errors
- AD的一些信息
- paintEvent调用时机
- LogCat里的错误提示 FATAL EXCEPTION: main
- LintCode:Paint House
- HDU 2476 String painter 区间dp
- 概率图模型
- bnu 51641 Certain Maze(bfs)(北师16校赛)
- caption标签,为表格添加标题和摘要 summary a mail
- bnu 51638 Air Hockey(三分+二分)(北师16校赛)
- hdu1302The Snail
- bnu 51640 Training Plan(类似区间dp)(北师16校赛)
- HDU 1023 Train ProblemII
- LeeCode-Contains Duplicate
- 关于main函数中argc和argv的简单介绍
- Fast-Start Failover工作过程及实例
- OpenGL vs2010 ActiveX Control Test Container
- B. Kuriyama Mirai's Stones