题目概述:
一个无向图,N个节点,求其最大团所含节点数
最大团就是节点最多的完全子图,完全图就是任意两个节点都直接相连的边的图
输入:
第一行N,其后N行,每行N个数,1代表行号点与列号点的直接相连
输入有多组,到N=0为止
限制:
1<=N<=50
输出:
每行一个整数,最大团所含节点数
多组输出之间没有空行
样例输入:
5
0 1 1 0 1
1 0 1 1 1
1 1 0 1 1
0 1 1 0 1
1 1 1 1 0
0
样例输出:
4
讨论:
只是个模版题,介绍了一下最大团的概念,比起用数学符号,还是文字比较直观
题解状态:
1653MS,1748K,1315 B,C++
题解代码:
#include<string.h>
#include<stdio.h>
#include<iostream>
#include<set>
#include<map>
#include<string>
#include<vector>
#include<math.h>
using namespace std;
#define INF 0x3f3f3f3f
#define maxx(a,b) ((a)>(b)?(a):(b))
#define minn(a,b) ((a)<(b)?(a):(b))
#define MAXN 53
#define memset0(a) memset(a,0,sizeof(a))
int g[MAXN][MAXN], dp[MAXN], stk[MAXN][MAXN], mx;//都是模版的
int dfs(int n, int ns, int dep)
{
if (!ns) {
if (dep > mx)
mx = dep;
return 1;
}
int i, j, k, p, cnt;
for (i = 0; i < ns; i++) {
k = stk[dep][i];
cnt = 0;
if (dep + n - k <= mx)
return 0;
if (dep + dp[k] <= mx)
return 0;
for (j = i + 1; j < ns; j++) {
p = stk[dep][j];
if (g[k][p])
stk[dep + 1][cnt++] = p;
}
dfs(n, cnt, dep + 1);
}
return 1;
}
int clique(int n)
{
int i, j, ns;
for (mx = 0, i = n - 1; i >= 0; i--) {
for (ns = 0, j = i + 1; j < n; j++)
if (g[i][j])
stk[1][ns++] = j;
dfs(n, ns, 1);
dp[i] = mx;
}
return mx;
}//模版结束
int fun(int N)
{
for (int p = 0; p < N; p++)
for (int o = 0; o < N; o++)
scanf("%d", &g[p][o]);//input//只要知道g是邻接矩阵就够用了
return clique(N);
}//input ends here
int main(void)
{
//freopen("vs_cin.txt", "r", stdin);
//freopen("vs_cout.txt", "w", stdout);
int N;
while (~scanf("%d", &N) && N) {//input
printf("%d\n", fun(N));//output
}
}
EOF