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
1 2
2 3
3 1
1 4
Sample Output
3
说明:选编号为1,2,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 }