bzoj 3632: 外太空旅行 最大团
3632: 外太空旅行
Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 389 Solved: 129
[Submit][Status]
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的同学参加,他们互相都是朋友。
HINT
Source
最大团在考试的时候用随机化+贪心正确性还是很高的,而且能轻而易举拓展到n=200及以上。
而DFS算法则可以看做是dfs优化的经典题目。
算法传送门:http://www.cnblogs.com/zhj5chengfeng/archive/2013/07/29/3224092.html
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define MAXN 102 #define MAXM 100000 int e[2][MAXM][2]; int map[MAXN][MAXN]; int q[MAXN],topq; int next[MAXN]; int n,m; int work() { topq=0; q[0]=0; int i,j; bool flag; for (i=1;i<n;i++) { flag=true; for (j=0;j<=topq;j++) { if (!map[i][q[j]]) { flag=false;break; } } if (flag) { q[++topq]=i; } } return topq+1; } int main() { freopen("input.txt","r",stdin); // freopen("output.txt","w",stdout); scanf("%d",&n); int i,j,k; int x,y,z; i=0; while (~scanf("%d%d",&e[1][i][0],&e[1][i][1])) { e[1][i][0]--; e[1][i][1]--; if (map[e[1][i][0]][e[1][i][1]])continue; m++; i++; } int ans=0; int cnt=0; while (cnt++<20000) { memset(map,0,sizeof(map)); for (i=0;i<m;i++) { map[e[cnt&1][i][0]][e[cnt&1][i][1]]=map[e[cnt&1][i][1]][e[cnt&1][i][0]]=true; } ans=max(ans,work()); for (i=0;i<n;i++) next[i]=i; for (i=0;i<n;i++) { x=rand()%n; y=rand()%n; swap(next[x],next[y]); } for (i=0;i<m;i++) { for (j=0;j<2;j++) { e[cnt&1^1][i][j]=next[e[cnt&1][i][j]]; } } } printf("%d\n",ans); }
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define MAXN 102 #define MAXM 100000 int e[MAXM][2]; int map[MAXN][MAXN]; int n,m; int s[MAXN][MAXN]; int tops[MAXN]; int l[MAXN],topl=-1; int ans=0; int rec[MAXN]; int dfs(int lev) { int i,j; int x; if (lev>ans) { ans=lev; return 1; } if (lev+tops[lev]+1<=ans)return 0; for (i=0;i<=tops[lev];i++) { x=s[lev][i]; tops[lev+1]=-1; if (i<tops[lev]&&lev+1+rec[s[lev][i+1]]<=ans)return 0; for (j=i;j<=tops[lev];j++) { if (map[x][s[lev][j]])s[lev+1][++tops[lev+1]]=s[lev][j]; } l[lev]=x; if (dfs(lev+1))return 1; } return 0; } int main() { freopen("input.txt","r",stdin); //freopen("output.txt","w",stdout); scanf("%d",&n); int i,j,k; int x,y,z; i=0; while (~scanf("%d%d",&e[i][0],&e[i][1])) { e[i][0]--; e[i][1]--; m++; i++; } int cnt=0; memset(map,0,sizeof(map)); for (i=0;i<m;i++) { map[e[i][0]][e[i][1]]=map[e[i][1]][e[i][0]]=true; } for (i=n-1;i>=0;i--) { for (j=i;j<n;j++) s[0][j-i]=j; tops[0]=n-i-1; dfs(0); rec[i]=ans; // cout<<i<<endl; } printf("%d\n",ans); }
by mhy12345(http://www.cnblogs.com/mhy12345/) 未经允许请勿转载
本博客已停用,新博客地址:http://mhy12345.xyz