BZOJ3632:外太空旅行(最大团,DFS)

Description

在人类的触角伸向银河系的边缘之际,普通人上太空旅行已经变得稀松平常了。某理科试验班有n个人,现在班主任要从中选出尽量多的人去参加一次太空旅行活动。
可是n名同学并不是和平相处的。有的人,比如小A和小B整天狼狈为奸,是好朋友;但还有的人,比如杜鲁门和赫鲁晓夫就水火不相容。这n名同学,由于是理科生,都非常的理性,所以“朋友的朋友就是朋友”和“敌人的朋友就是敌人”这两句话对这些同学无效。换句话说,有可能小A和小B是朋友,小B和小C是朋友,但是小A和小C两人势如水火。
任意两个人之间要不就是敌人,要不就是朋友。
因为在太空船上发生人员斗殴事件是很恶劣也很危险的,因此选出来参加旅行活动的同学必须互相之间都是朋友。你的任务就是确定最多可以选多少人参加旅行。

Input

第一行一个整数n(1<=n<=50)。所有的同学按照1~n编号。
接下来若干行,每行两个用空格隔开的整数a, b(1<=a,b<=n),表示a和b是朋友。
注意:如果一个数对(x,y)(或者(y,x))没有在文件中出现,那么编号为x和y的两个同学就是敌人。

Output

仅仅一个数,即最多可以选多少人参加活动。

Sample Input

4
1 2
2 3
3 1
1 4

Sample Output

3
说明:选编号为1,2,3的同学参加,他们互相都是朋友。

Solution

最大团……$NPC$直接爆搜加剪枝。

具体搜法可以看这个博客

Code

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<vector>
 5 #define N (59)
 6 using namespace std;
 7 
 8 int n,u,v,ans,Max[N],G[N][N];
 9 
10 bool DFS(vector<int> &g,int x)
11 {
12     int s=g.size();
13     if (!s) return x>ans?ans=x:0;
14     for (int i=0; i<s; ++i)
15     {
16         if (x+s<=ans) return 0;
17         if (x+Max[g[i]]<=ans) return 0;
18         vector<int>v; v.clear();
19         for (int j=i+1; j<s; ++j)
20             if (G[g[i]][g[j]]) v.push_back(g[j]);
21         if (DFS(v,x+1)) return 1;
22     }
23     return 0;
24 }
25 
26 int main()
27 {
28     scanf("%d",&n);
29     while (scanf("%d%d",&u,&v)!=EOF) G[u][v]=G[v][u]=1;
30     for (int i=n; i>=1; --i)
31     {
32         vector<int>v; v.clear();
33         for (int j=i+1; j<=n; ++j)
34             if (G[i][j]) v.push_back(j);
35         DFS(v,1); Max[i]=ans;
36     }
37     printf("%d\n",ans);
38 }
posted @ 2019-02-26 17:21  Refun  阅读(223)  评论(0编辑  收藏  举报