zoukankan      html  css  js  c++  java
  • 暴力搜索 + 剪枝

    A clique is a complete graph, in which there is an edge between every pair of the vertices. Given a graph with NNN vertices and MMM edges, your task is to count the number of cliques with a specific size SSS in the graph.

    Input

    The first line is the number of test cases. For each test case, the first line contains 333 integers N,MN,MN,M and SSS (N≤100,M≤1000,2≤S≤10)(N le 100,M le 1000,2 le S le 10)(N100,M1000,2S10), each of the following MMM lines contains 222 integers uuu and vvv (1≤u<v≤N)(1 le u < v le N)(1u<vN), which means there is an edge between vertices uuu and vvv. It is guaranteed that the maximum degree of the vertices is no larger than 202020.

    Output

    For each test case, output the number of cliques with size SSS in the graph.

    样例输入

    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

    样例输出

    3
    7
    15

    题意 : 给你一张图,询问这个图中有多少个大小为 s 的完全子图
    思路分析 : 因为数据比较小,因此我们直接暴力去找就可以了,对于选出的任意一个子图,只需要判断任意两条边是否都有边即可, 但是只是单纯的这样操作会超时,因为寻找了很多无用的状态,例如 1, 3, 5
    大小为 3 的完全图,我们再寻找的过程中 1, 5, 3也会被找到,其实本质上是同一个完全子图,这里我们只需要在建边的时候优化一下就可以了,建的时候我们只建立单向的边,即从小到大的方向上面建边
    代码示例 :

    int n, m, k;
    vector<int>ve[105];
    int mp[105][105];
    int f[105];
    int ans = 0;
    int vis[105];
    struct edg
    {
        int to, next;    
    }edge[1005];
    int head[1005];
    int cnt = 1;
    
    void addedge(int u, int v){
        edge[cnt].next = head[u];    
        edge[cnt].to = v;
        head[u] = cnt++;
    }
    
    void dfs(int x, int fa, int cnt){
        int sign = 0;
        for(int i = 1; i < cnt; i++){
            if (mp[x][f[i]] == 0) {sign = 1; break;}
        }    
        if (sign) return;
        f[cnt] = x; 
        
        if (cnt == k) {ans++; return;}
        for(int i = head[x]; i != -1; i = edge[i].next){
            int to = edge[i].to;
            if (to == fa) continue;
            int sign = 0;
            if (!vis[to]) { 
                vis[to] = 1;
                dfs(to, x, cnt+1);
                vis[to] = 0;
            }
        }
    }
    
    int main() { 
        int t;
        int a, b;
        
        cin >> t;
        while(t--){
            scanf("%d%d%d", &n, &m, &k);
            memset(mp, 0, sizeof(mp));
            memset(vis, 0, sizeof(vis));
            
            memset(head, -1, sizeof(head));
            cnt = 1;
            for(int i = 1; i <= m; i++){
                scanf("%d%d", &a, &b);
                if (a > b) swap(a, b);
                addedge(a, b);
                mp[a][b] = mp[b][a] = 1;            
            }
            ans = 0;
            for(int i = 1; i <= n; i++){
                dfs(i, 0, 1); 
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
    
    东北日出西边雨 道是无情却有情
  • 相关阅读:
    BZOJ4916: 神犇和蒟蒻 杜教筛
    BZOJ 4816: [Sdoi2017]数字表格 莫比乌斯反演
    BZOJ 4407: 于神之怒加强版 莫比乌斯反演 + 线筛积性函数
    BZOJ 3963: [WF2011]MachineWorks 斜率优化 + splay动态维护凸包
    BZOJ 1492: [NOI2007]货币兑换Cash 斜率优化 + splay动态维护凸包
    BZOJ 3306: 树 LCT + set 维护子树信息
    小A与最大子段和 斜率优化 + 二分 + 细节
    BZOJ 3675: [Apio2014]序列分割 动态规划 + 斜率优化 + 卡精度
    BZOJ 2726: [SDOI2012]任务安排 斜率优化 + 凸壳二分 + 卡精
    luoguP2365 任务安排 斜率优化 + 动态规划
  • 原文地址:https://www.cnblogs.com/ccut-ry/p/9756946.html
Copyright © 2011-2022 走看看