• HDU


    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
    ",ans);
        }
        return 0;
    }
     
  • 相关阅读:
    Java中抽象类和接口的区别
    servlet的转发与重定向
    JSP知识点
    过滤器与拦截器
    java关键字 super 和 this
    oracle 基础
    java 集合
    java 内部类
    java 数组详解
    图,深度优先遍历与广度优先遍历
  • 原文地址:https://www.cnblogs.com/ZGQblogs/p/9890878.html
Copyright © 2020-2023  润新知