hdu5952 Counting Cliques(2016 icpc 沈阳)

7 篇文章 0 订阅

Counting Cliques

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


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
 
 
34 3 21 22 33 45 9 31 31 41 52 32 42 53 43 54 56 15 41 21 31 41 51 62 32 42 52 63 43 53 64 54 65 6
 
Sample Output
 
 
3715

题意:给你n个点 m条边 计算有s个节点的完全子图的数目


思路:dfs;对每个点进行一次搜索,用一个temp数组保存已经加入团的点,每次加入一个新点的时候判断是否满足完全子图的条件;


ac代码:

    #include<bits/stdc++.h>

    using namespace std;

    vector<int>G[105];
    int ma[105][105];
    int cnt,dis;
    int n,m,s;
    int temp[105];

    void dfs(int x,int dis,int temp[105])
    {
        if(dis == s)
        {
            cnt ++;
            return;
        }
        else
        {
            bool f;
            for(int i = 0; i < G[x].size(); i++)
            {
                int v = G[x][i];
                f = true;
              for(int j = 1; j <= dis; j++)
              {
                  if(!ma[v][temp[j]])
                   {
                       f = false;
                        break;
                   }
              }
              if(f)
              {
                  dis++;
                  temp[dis] = v;
                  dfs(v,dis,temp);
                  temp[dis] = 0;
                  dis--;
              }


            }
        }
        return ;
    }

    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            memset(ma,0,sizeof(ma));
            scanf("%d %d %d",&n,&m,&s);
           for(int i = 1; i <= n; i++)
            G[i].clear();
            cnt = 0;
            int x,y;
            for(int i = 0; i < m; i++)
            {
                scanf("%d %d",&x,&y);
                G[x].push_back(y);
                ma[x][y] = ma[y][x] = 1;

            }
            for(int i = 1; i <= n; i++)
            {
                dis = 1;
                temp[1] = i;
                dfs(i,dis,temp);
            }
            printf("%d\n",cnt);
        }
    }





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值