题目:
http://acm.hdu.edu.cn/showproblem.php?pid=5952
题意:
给定一个无向图图,问这个图中含有多少个顶点数为s的子图是完全图
思路:
首先把每个点邻接的点存到相应的数组里,遍历每个点,如果一个是完全图的子图中有当前点,那么子图中的其他点一定全部与当前点邻接,于是在当前点邻接的所有点中枚举出s-1个点,判断枚举出的s个点是否构成完全图。本题数据很强,一直TLE,后来判断是否完全图的时候不判断当前点与其他点是否邻接(当前点与枚举出的其他点一定邻接),就过了,,,一定要不择手段的优化代码,莫名就过了。。。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
#include <cmath>
#include <queue>
#include <vector>
using namespace std;
typedef long long ll;
const int N = 110;
int arr[N][25];
int idx[N];
int tmp[N];
bool edge[N][N];
int n, m, s, res;
bool check(int *tmp, int k)
{
for(int i = 1; i < k; i++)
for(int j = i+1; j < k; j++)
if(edge[tmp[i]][tmp[j]] == false) return false;
return true;
}
void dfs(int v, int th, int k, int cur, int dep)
{
if(cur > dep)
{
if(check(tmp, k)) res++;
return;
}
for(int i = th; i < idx[v]-(dep-cur); i++)
if(tmp[k-1] < arr[v][i])
{
tmp[k] = arr[v][i];
dfs(v, i+1, k+1, cur+1, dep);
}
}
int scan()
{
int sum = 0;
char ch;
while((ch = getchar()) >= '0' && ch <= '9') sum = sum * 10 + ch-'0';
return sum;
}
void out(int a)
{
if(a > 9) out(a / 10);
putchar(a % 10 + '0');
}
int main()
{
int t;
t = scan();
//scanf("%d", &t);
while(t--)
{
n = scan(), m = scan(), s = scan();
//scanf("%d%d%d", &n, &m, &s);
memset(idx, 0, sizeof idx);
for(int i = 0; i <= n; i++)
for(int j = 0; j <= n; j++)
edge[i][j] = false;
for(int i = 1; i <= m; i++)
{
int a, b;
a = scan(), b = scan();
//scanf("%d%d", &a, &b);
arr[a][idx[a]++] = b, arr[b][idx[b]++] = a;
edge[a][b] = edge[b][a] = true;
}
for(int i = 1; i <= n; i++)
sort(arr[i], arr[i] + idx[i]);
res = 0;
for(int i = 1; i <= n; i++)
{
int k = 0;
tmp[k++] = i;
dfs(i, 0, k, 1, s - 1);
}
out(res);
putchar('\n');
//printf("%d\n", res);
}
return 0;
}