题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1530
求最大团裸题。
代码:
#include<iostream> #include<cstring> #include<cstdio> using namespace std; int n; int mp[55][55],mark[500]; int cn,maxx; //没优化,跑9000+ms int t=0; void dfs(int x) //dfs(1); { if(x>n) { maxx=cn; return; } int flag=1; for(int i=1; i<x; i++) { if(mark[i]&&!mp[x][i]) { flag=0; break; } } if(flag) { cn++; mark[x]=1; dfs(x+1); cn--; } if(cn+n-x+1>maxx) ///这句话看了好久都没懂是什么意思 { mark[x]=0; dfs(x+1); } } int main() { while(scanf("%d",&n)==1 && n) { memset(mp,0,sizeof(mp)); memset(mark,0,sizeof(mark)); for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) scanf("%d",&mp[i][j]); cn=maxx=0; dfs(1); printf("%d\n",maxx); } return 0; }
模板2:
#include<cstdio> #include<cstring> const int N=1010; //最大团模板 bool a[N][N];//a为图的邻接表(从1开始) int cnt[N],group[N],vis[N];//cnt[N]表示当前最大团的节点数,group[N]用以寻找一个最大团集合 int n,m,ans;//ans表示最大团 //dfs(i,1); bool dfs(int u,int pos)//u为当从前顶点开始深搜,pos为深搜深度(即当前深搜树所在第几层的位置) { int i,j; for(i=u+1; i<=n; i++)//按递增顺序枚举顶点 { if(cnt[i]+pos<=ans) return 0;//剪枝 if(a[u][i]) { //与目前团中元素比较,取 Non-N(i) for(j=0; j<pos; j++) if(!a[i][vis[j]]) break; if(j==pos) { //若为空,则皆与 i 相邻,则此时将i加入到 最大团中 vis[pos]=i;//深搜层次也就是最大团的顶点数目,vis[pos]=i表示当前第pos小的最大团元素为i(因为是按增顺序枚举顶点 ) if(dfs(i, pos+1)) return 1; } } } if(pos>ans) { for(i=0; i<pos; i++) group[i]=vis[i]; // 更新最大团元素 ans=pos; return 1; } return 0; } void maxclique()//求最大团 { ans=-1; for(int i=n; i>0; i--) { vis[0]=i; dfs(i,1); cnt[i]=ans; } } int main() { while(scanf("%d",&n)==1 && n) { if(n==0) break; int x,y; memset(a,0,sizeof(a)); for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) scanf("%d",&a[i][j]); maxclique(); if(ans<0) ans=0;//ans表示最大团 printf("%d\n",ans); } }
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; int n,path[61][61],s[61],dp[61],ans; bool is_clique(const int ed,const int point) { for(int i=1; i<ed; i++) if(!path[s[i]][point]) return false; return true; } void dfs(int depth,int now) { if(depth+n-now+1<=ans||depth+dp[now]<=ans) return; for(int i=now; i<=n; i++) { if(is_clique(depth+1,i)) { s[depth+1]=i; dfs(depth+1,i+1); } } if(depth>ans) ans=depth; } int main() { while(scanf("%d",&n)==1 && n) { for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) scanf("%d",&path[i][j]); memset(dp,0,sizeof(dp)); ans=0; dp[n]=1; for(int i=n-1; i>=1; i--) { s[1]=i; dfs(1,i+1); dp[i]=ans; } printf("%d\n",dp[1]); } return 0; }
时间: 2024-11-10 00:51:30