题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1530
求最大团裸题。
模板:maxx即为所求的最大团的值。
#include<iostream> #include<cstring> #include<cstdio> using namespace std; int mp[110][110],mark1[505],mark2[505]; int n,cnt,maxx; void dfs(int x) { if(x>n) // 如果枚举了所有的节点 { maxx=cnt; memcpy(mark1,mark2,sizeof(mark2)); // 用一个更大的极大团替代原有的极大团 return; } int flag=true; for(int i=1; i<x; i++) // 检测新加入的点是否到团中的其他节点都存在一条边 { if(mark2[i] && !mp[i][x]) { flag=false; break; } } if(flag) // 如果该节点满足在这个团中 { mark2[x]=1,cnt++; // 该节点被加入到完全子图中去 dfs(x+1); mark2[x]=0,cnt--; } if (cnt+n-x>maxx) // 跳过x节点进行搜索同时进行一个可行性判定 dfs(x+1); } int main() { while(scanf("%d",&n)==1 && n) { memset(mark1,0,sizeof(mark2)); memset(mark2,0,sizeof(mark2)); maxx=cnt=0; for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) scanf("%d",&mp[i][j]); dfs(1); printf("%d\n",maxx); } return 0; }
代码1:
#include<iostream> #include<cstring> #include<cstdio> using namespace std; int n; int mp[55][55],mark[500]; int cn,maxx; //没优化,跑9000+msvoid 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; }