UVA 818 (dfs+二进制枚举)
题意:给n个点,然后给几个数对,每个数字代表一个圆环,表示这两个环连在一起,然后求需要打开几个环,能够让这n个环形成一个链。
分析:因为n的范围是1~15,所以可以二进制枚举哪个环需要断开,然后在该状态下判断是否满足条件(即当前没有环,并且所有的都没有两个分支),并且判断需要断开的部分是否大于等于原来的链子。
 
 1 #include <stdio.h>
 2 #include <string.h>
 3 #define min(a,b) (a)<(b)?(a):(b)
 4 #define INF 0x3f3f3f3f
 5 const int N = 20;
 6 int n, g[N][N], vis[N], cn;
 7 bool two(int s)
 8 {
 9     for (int i = 0; i < n; i++)
10     {
11         if (s&(1<<i)) continue;
12         int num = 0;
13         for (int j = 0; j < n; j++)
14         {
15             if (s&(1<<j)) continue;
16             if (g[i][j]) num++;
17         }
18         if (num > 2) return true;
19     }
20     return false;
21 }
22 bool dfs(int s, int now, int fa)
23 {
24     vis[now] = 1;
25     for (int i = 0; i < n; i++)
26     {
27         if (!g[now][i] || (s&(1<<i)) || i == fa) continue;
28         if (vis[i]) return true;
29         if (dfs(s, i, now)) return true;
30     }
31     return false;
32 }
33 bool circle(int s)
34 {
35     for (int i = 0; i < n; i++)
36     {
37         if (vis[i] || (s&(1<<i))) continue;
38         cn++;
39         if (dfs(s, i, -1)) return true;
40     }
41     return false;
42 }
43 int cal(int s)
44 {
45     return s == 0 ? 0 : cal(s / 2) + (s&1);
46 }
47 int solve()
48 {
49     int ans = INF;
50     int s = (1<<n);
51     for (int i = 0; i < s; i++)
52     {
53         cn = 0;
54         memset(vis, 0, sizeof(vis));
55         if(two(i) || circle(i)) continue;///如果有两个分支或者有环就不满足
56         if (cal(i) >= cn - 1)///如果开的部分大于剩下的链数
57             ans = min(cal(i), ans);
58     }
59     return ans;
60 }
61 int main()
62 {
63     int cas = 0;
64     while (~scanf("%d", &n) && n)
65     {
66         int a, b;
67         memset(g, 0, sizeof(g));
68         while (~scanf("%d%d", &a, &b) && a != -1 && b != -1)
69             g[a - 1][b - 1] = g[b - 1][a - 1] = 1;
70         printf("Set %d: Minimum links to open is %d\n", ++cas, solve());
71     }
72     return 0;
73 }
    人生就像心电图,想要一帆风顺,除非game-over
 
                    
                

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号