hdu 5952 连通子图

Counting Cliques

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

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

思路:构造一个团,如果一个点与这个团的所有点都有边,则将其加入团中,统计含s个点的团的个数。关于优化,可以建单向边来减少搜索量。

代码:

 1 #include<bits/stdc++.h>
 2 //#include<regex>
 3 #define db double
 4 #include<vector>
 5 #define ll long long
 6 #define vec vector<ll>
 7 #define Mt  vector<vec>
 8 #define ci(x) scanf("%d",&x)
 9 #define cd(x) scanf("%lf",&x)
10 #define cl(x) scanf("%lld",&x)
11 #define pi(x) printf("%d
",x)
12 #define pd(x) printf("%f
",x)
13 #define pl(x) printf("%lld
",x)
14 #define MP make_pair
15 #define PB push_back
16 #define inf 0x3f3f3f3f3f3f3f3f
17 #define fr(i,a,b) for(int i=a;i<=b;i++)
18 const int N=1e3+5;
19 const int mod=1e9+7;
20 const int MOD=mod-1;
21 const db  eps=1e-18;
22 using namespace std;
23 bool d[105][105];
24 int n,m,s,t;
25 int ans;
26 vector<int> g[N];
27 void dfs(int u,int *a,int cnt)
28 {
29     if(cnt==s){
30         ans++;
31         return;
32     }
33     bool ok;
34     for(int i=0;i<g[u].size();i++)
35     {
36         ok=1;
37         int v=g[u][i];
38         for(int j=1;j<=cnt;j++){
39             if(!d[a[j]][v]) {ok=0;break;}
40         }
41         if(ok)
42         {
43             a[++cnt]=v;//加点
44             dfs(v,a,cnt);//继续搜
45             a[cnt--]=0;
46         }
47     }
48 }
49 int main(){
50 //freopen("data.in","r",stdin);
51 //freopen("data.out","w",stdout);
52     ci(t);
53     while(t--)
54     {
55         ci(n),ci(m),ci(s);
56         ans=0;
57         for(int i=1;i<=n;i++) g[i].clear();
58         memset(d,0,sizeof(d));
59         for(int i=0;i<m;i++){
60             int u,v;
61             ci(u),ci(v);
62             if(u>v) swap(u,v);
63             g[u].push_back(v);
64             d[u][v]=d[v][u]=1;
65         }
66         for(int i=1;i<=n;i++){
67             if(g[i].size()>=s-1){
68                 int a[105];
69                 a[1]=i;//构建团
70                 int cnt=1;
71                 dfs(i,a,cnt);
72             }
73         }
74         pi(ans);
75     }
76     return 0;
77 }
原文地址:https://www.cnblogs.com/mj-liylho/p/7624924.html