Counting Cliques
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1639 Accepted Submission(s): 641
Problem Description
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.
Input
The first line is the number of test cases. For each test case, the first line contains 3 integers N,M and S (N ≤ 100,M ≤ 1000,2 ≤ S ≤ 10), each of the following M lines contains 2 integers u and v (1 ≤ u < v ≤ N), which means there is an edge between vertices u and v. It is guaranteed that the maximum degree of the vertices is no larger than 20.
Output
For each test case, output the number of cliques with size S in the graph.
Sample Input
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
Sample Output
3 7 15思路:写在代码的注释上了//题意:给你一些点一些边 要你求 s 个顶点的完全图有多少个。思路 为了判重建图的时候把小的点指向大的点,有点像组合, //这样就不会重复了,用一个数组保存已经求的的完全图的点,然后往里面加点;之前用vector做,超时了 #include<stdio.h> #include<string.h> #include<vector> using namespace std; #define MAX 200 #define MAXM 2050 struct edge { int to,next; }edges[MAXM]; int n,m,s; int map[MAX][MAX]; int head[MAX],tot; //vector<edge>edges; //vector<int>G[MAX]; int aa[MAX]; int ans; /*void addedge(int x,int y) { edge a={x,y}; edges.push_back(a); G[x].push_back(edges.size()-1); }*/ void addedge(int x,int y) { edges[tot].to=y; edges[tot].next=head[x]; head[x]=tot++; /* edges[tot].to=x; edges[tot].next=head[y]; head[y]=tot++; */ } void dfs(int u,int count) { if(count==s)//当完全图点的个数增加到s个 就计数器加1 { ans++; return ; } for(int i=head[u];i!=-1;i=edges[i].next) { int v=edges[i].to; int flag=1; for(int j=1;j<=count;j++)//判断与之相连的点跟之前完全图的点集合里 是不是每个都有一条边 { if(map[v][aa[j]]==0) { flag=0; break; } } if(flag){//有就放进点集合 aa[count+1]=v; dfs(v,count+1); } } } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d %d %d",&n,&m,&s); /* for(int i=1;i<=n;i++) G[i].clear(); edges.clear();*/ tot=0; memset(head,-1,sizeof(head)); memset(map,0,sizeof(map)); for(int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); if(x>y) swap(x,y); addedge(x,y);//从小到大建图 map[x][y]=1;//方便查找有没有边 map[y][x]=1; } ans=0; for(int i=1;i<=n-s+1;i++) { aa[1]=i; dfs(i,1); } printf("%d\n",ans); } }