【HDOJ5952】Counting Cliques(团,dfs)

题意:给定一张n点m边的图,求大小为S的团的个数

 N ≤ 100,M ≤ 1000,2 ≤ S ≤ 10,保证点的度不超过20

思路:dfs

因为每个点可能不止属于一个极大团,所以不能求出极大团然后计数

dfs搜索所有的合法方案,只搜索所有点编号递增的方案,这样就不会有重复计数的问题了

也算是常见的避免重复计数的技巧了

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<string>
  4 #include<cmath>
  5 #include<iostream>
  6 #include<algorithm>
  7 #include<map>
  8 #include<set>
  9 #include<queue>
 10 #include<vector>
 11 #include<bits/stdc++.h>
 12 using namespace std;
 13 typedef long long ll;
 14 typedef unsigned int uint;
 15 typedef unsigned long long ull;
 16 typedef pair<int,int> PII;
 17 typedef vector<int> VI;
 18 #define fi first
 19 #define se second 
 20 #define MP make_pair
 21 #define N  110
 22 #define M  2100
 23 #define MOD 1000000007
 24 #define eps 1e-8 
 25 #define pi acos(-1)
 26 
 27 int f[N][N],head[M],vet[M],nxt[M],c[N],n,m,s,tot,ans;
 28 
 29 int read()
 30 { 
 31    int v=0,f=1;
 32    char c=getchar();
 33    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
 34    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 35    return v*f;
 36 }
 37 
 38 void add(int a,int b)
 39 {
 40     nxt[++tot]=head[a];
 41     vet[tot]=b;
 42     head[a]=tot;
 43 }
 44 
 45 void dfs(int k,int u)
 46 {
 47     //for(int i=1;i<=k;i++) printf("%d ",c[i]);
 48     //printf("\n"); 
 49     if(k==s)
 50     {
 51         ans++;
 52         return;
 53     }
 54     int e=head[u];
 55     while(e)
 56     {
 57         int v=vet[e];
 58         if(v<u){e=nxt[e]; continue;}
 59         int flag=1;
 60         for(int i=1;i<=k;i++)
 61          if(!f[c[i]][v]){flag=0; break;}
 62         if(flag)
 63         {
 64             c[k+1]=v;
 65             dfs(k+1,v);
 66             c[k+1]=0;
 67         }
 68         e=nxt[e];
 69     }
 70 }
 71             
 72         
 73 int main()
 74 {
 75     freopen("hdoj5952.in","r",stdin);
 76     freopen("hdoj5952.out","w",stdout);
 77     int cas;
 78     scanf("%d",&cas);
 79     while(cas--)
 80     {
 81         scanf("%d%d%d",&n,&m,&s);
 82         for(int i=1;i<=n;i++) head[i]=0;
 83         for(int i=1;i<=n;i++)
 84          for(int j=1;j<=n;j++) f[i][j]=0;
 85         tot=0;
 86         for(int i=1;i<=m;i++) 
 87         {
 88             int x,y;
 89             scanf("%d%d",&x,&y);
 90             add(x,y);
 91             add(y,x);
 92             f[x][y]=f[y][x]=1;
 93         }
 94         ans=0;
 95         for(int i=1;i<=n;i++) 
 96         {
 97             c[1]=i;
 98             dfs(1,i);
 99             c[1]=0;
100         }
101         printf("%d\n",ans);
102     }
103     return 0;
104 }
105      

 

posted on 2018-10-04 16:22  myx12345  阅读(202)  评论(0编辑  收藏  举报

导航