hdu 5952Counting Cliques(dfs 优化)

来源:互联网 发布:mp4视频格式转换软件 编辑:程序博客网 时间:2024/06/05 08:10

Counting Cliques

Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2660    Accepted Submission(s): 972


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
34 3 21 22 33 45 9 31 31 41 52 32 42 53 43 54 56 15 41 21 31 41 51 62 32 42 52 63 43 53 64 54 65 6
 

Sample Output
3715


题意:给N个点M条边,求大小位S的集合的个数,要求集合内的元素两两有边(完全图)。

解:因为点少边多,为了减少重复计数 只按照点序号由小到大建单项边 因为完全图一定是环 这样就可以避免重复计数 并且大大减少了遍历的次数

其他的xjb剪枝都能过 因为最关键的是建图操作(骚)

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <bits/stdc++.h>using namespace std;const int N = 1e6+10;typedef long long LL;int head[110], cnt;struct node{    int to, next;} p[N];int w[105][105], vis[105], c[110], c1[110], val[105];int ans;void init(){    memset(head,-1,sizeof(head));    memset(w,0,sizeof(w));    memset(c,0,sizeof(c));    cnt=0,ans=0;    return ;}void add(int u,int v){    p[cnt].to=v,p[cnt].next=head[u];    head[u]=cnt++;    return ;}int vx[110];void dfs(int u,int d,int s,int n){    for(int i=1; i<d; i++)        if(w[vx[i]][u]==0) return ;    if(d==s)    {        ans++;        return ;    }    for(int i=head[u]; i!=-1; i=p[i].next)    {        int v=p[i].to;        if(c[v]) continue;        vx[d+1]=v;        dfs(v,d+1,s,n);    }    return ;}int main(){    int t;    scanf("%d", &t);    while(t--)    {        int n, m, s;        scanf("%d %d %d", &n, &m, &s);        init();        for(int i=0; i<m; i++)        {            int x, y;            scanf("%d %d", &x, &y);            if(w[x][y]==0)            {                w[x][y]=1,w[y][x]=1;                if(x>y)swap(x,y);                add(x,y);            }        }        for(int i=1; i<=n; i++)        {            vx[1]=i,c[i]=1;            dfs(i,1,s,n);        }        printf("%d\n",ans);    }    return 0;}






原创粉丝点击