HDU - 5952 Counting Cliques(DFS)

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.

InputThe 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.OutputFor 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

思路:如何找到一个k阶的完全图?如果一个图是完全图,那么引入一个新的点,这个点与原图中的每一点都有边相连,新图还是完全图。用了num数组来记录原图上的点。建图时,、只建了从编号小的点到编号大的点之间的边。这是由于,每次没有必要建立反向边。反而不建反向边的话,会少了去重的过程。代码:
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#define fuck(x) cout<<#x<<" = "<<x<<endl;
#define ls (t<<1)
#define rs ((t<<1)+1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 108;
const int inf = 2.1e9;
const ll Inf = 999999999999999999;
const int mod = 1000000007;
const double eps = 1e-6;
const double pi = acos(-1);
vector<int>u[maxn];
int n,m,k;
int ans;
int top;
int num[maxn];
bool mp[maxn][maxn];
void dfs(int t,int d)
{
    if(d==k){ans++;return;}
    int siz = u[t].size();
    bool flag = false;
    for(int i=0;i<siz;i++){
        int cnt = u[t][i];
        flag = false;
        for(int j=1;j<=top;j++){
            if(!mp[cnt][num[j]]){flag = true;break;}
        }
        if(flag){continue;}

        num[++top]=cnt;
        dfs(cnt,d+1);
        top--;
    }
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
        ans = 0;
        scanf("%d%d%d",&n,&m,&k);
        memset(mp,0,sizeof(mp));
        for(int i=1;i<=n;i++){
            u[i].clear();
        }
        int x,y;
        for(int i=1;i<=m;i++){
            scanf("%d%d",&x,&y);
            if(x>y){swap(x,y);}
            u[x].push_back(y);
            mp[x][y]=mp[y][x]=true;
        }

        for(int i=1;i<=n;i++){
            num[++top]=i;
            dfs(i,1);
            top--;
        }
        printf("%d\n",ans);
    }
    return 0;
}
 

原文地址:https://www.cnblogs.com/ZGQblogs/p/9890878.html

时间: 2024-11-09 16:53:25

HDU - 5952 Counting Cliques(DFS)的相关文章

HDU 5952 Counting Cliques(dfs)

Counting Cliques Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1855    Accepted Submission(s): 735 Problem Description A clique is a complete graph, in which there is an edge between every pai

HDU 5952 Counting Cliques -暴力

现场赛手速三题,这题一直没写. 直接暴力,注意点只有一个!单向建边,从小点到大点. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 struct edge 6 { 7 int to; 8 int next; 9 }E[1011]; 10 int head[111]; 11 bool e[111][111]; 12 int tot; 13 int

Counting Cliques HDU - 5952 单向边dfs

题目:题目链接 思路:这道题vj上Time limit:4000 ms,HDU上Time Limit: 8000/4000 MS (Java/Others),且不考虑oj测评机比现场赛慢很多,但10月5号的计蒜客重现赛只给了1000ms确实有点过分吧,好久没有做这种简单dfs做到自闭了,,,题目并不难,注意剪枝就好了,建图时建标号小的点指向标号大的点的单向边,这样按标号从小到大搜一遍就好了,完全图的任意两个点都要有边,按点的标号搜到第n-s+1个点,因为后面所有的点加起来都组不成点数为s的完全子

hdu 3887 Counting Offspring dfs序+树状数组

Counting Offspring Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description You are given a tree, it’s root is p, and the node is numbered from 1 to n. Now define f(i) as the number of nodes whose numbe

HDU 3887 Counting Offspring(DFS序求子树权值和)

Problem Description You are given a tree, it's root is p, and the node is numbered from 1 to n. Now define f(i) as the number of nodes whose number is less than i in all the succeeding nodes of node i. Now we need to calculate f(i) for any possible i

HDU 2952 Counting Sheep (DFS找联通块)

题目链接:请戳这里.   题目大意及思路:读懂题意就好了,就是DFS找联通块. 没什么好说的,见代码吧. #include<cstdio> #include<cstring> #include<algorithm> #define N 100+5 using namespace std; int n,m; char g[N][N]; int dir[4][2]={1,0,0,1,-1,0,0,-1}; void dfs(int x,int y) { for(int i=

HDU 5952

HDU 5952 Counting Cliques 题意:给一个图,给出一个值s,问这个图里面有多少个s条边的完全图. 题解:直接dfs,因为每个点最多只有20个出度,只是在记录时需要单向记录,dfs的时候也就从前往后扫了.现在终于知道当时T掉的原因了...原来记录点时set改成数组就不会超时了.纪念一发. 正确代码 #include <cstdio> #include <cstring> #include <iostream> #include <algorit

【算法系列学习】巧妙建图,暴搜去重 Counting Cliques

E - Counting Cliques http://blog.csdn.net/eventqueue/article/details/52973747 http://blog.csdn.net/yuanjunlai141/article/details/52972715 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<

hdu 1501 Zipper (dfs+记忆化搜索)

Zipper Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6491    Accepted Submission(s): 2341 Problem Description Given three strings, you are to determine whether the third string can be formed