A clique is a complete graph, in which there is an edge between every pair of the vertices. Given a graph with N vertices and M edges, your task is to count the number of cliques with a specific size S in the graph.
3 4 3 2 1 2 2 3 3 4 5 9 3 1 3 1 4 1 5 2 3 2 4 2 5 3 4 3 5 4 5 6 15 4 1 2 1 3 1 4 1 5 1 6 2 3 2 4 2 5 2 6 3 4 3 5 3 6 4 5 4 6 5 6
3 7 15
给出一个图,然后问你有多少个节点数为s的完全子图; 题目思路:
首先我们肯定去想如何去判断是否为完全子图,我们可以想到从某一个点出发,然后对于这个点去扩展,把有可能为完全图中的节点加入到数组中,然后对于扩展出的节点再去扩展节点,如果对于这个点如果跟集合中的点都联通,那么我们就把它加入集合,并且用它去扩展,重复这个过程,直到集合内的点有s个
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<sstream>
#include<cmath>
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 100+5;
int head[maxn];
int vis[maxn];
int tot;
int T;
int n,m,s;
int mp[maxn][maxn];
void init()
{
memset(head,-1,sizeof(head));
tot = 0;
}
int du[maxn];
struct node
{
int u,v;
int net;
}E[maxn*10];
void build(int u,int v){
E[tot].u =u ;
E[tot].v = v;
E[tot].net = head[u];
head[u] = tot++;
}
LL ans;
int a[21];
void dfs(int u,int sum,int fa)
{
if(sum==s){
// cout<<fa<<--endl;
ans++;
return;
}
if(du[u]<s-1)
return;
for(int i = head[u];~i;i = E[i].net){
int to = E[i].v;
if(to==fa) continue;
int falg = 1;
for(int j = 0;j<sum;j++){
if(mp[a[j]][to]==-1){
falg = 0;
break;
}
}
if(falg){
a[sum++] = to;
dfs(to,sum,u);
sum--;
}
}
}
int main()
{
scanf("%d",&T);
while(T--){
init();
scanf("%d%d%d",&n,&m,&s);
memset(du,0,sizeof(du));
memset(mp,-1,sizeof(mp));
ans = 0;
for(int i = 0;i<m;i++){
int a,b;
scanf("%d%d",&a,&b);
if(a>b) swap(a,b);
build(a,b);
mp[a][b] = 1;
mp[b][a] = 1;
du[a]++;
du[b]++;
}
for(int i = 1;i<=n;i++){
a[0] = i;
// cout<<"fuck"<<endl;
dfs(i,1,-1);
}
// cout<<ans<<endl;
printf("%d\n",ans);
}
}