『HDU 5952』Counting Cliques 沈阳赛

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5952

题意:
就是给你一个图,要找里面的子图满足节点数为S的完全图的个数.

解释:
这道题dfs一遍就行了,我用了两种方法存图,一个是邻接矩阵,一个是邻接表.我用一个队列来存我选择的节点,通过普通画图都知道,我新加一个u节点,究竟能不能加,我就看我之前的节点和这个u点有没有连边,有连边才遍历下一层选点. 然后会有重复.有2个去重的方法
1.遍历过的根的点,不选!
2.存边的时候,只存比当前大的边.然后即可. 这样成环的时候不会重复。
(千万不能在遍历的时候再判断比当前点大的点,这样存的边会T.)
我试过用2个longlong来模判断和之前的点有没连接…这样就可以缩小判断到2次…我不知道为什么会WA了,莫名其妙了.只有这种判断10次的方法才能过…

/* Author:GavinjouElephant
 * Title:
 * Number:
 * main meanning:
 *
 *
 *
 */


#include <iostream>
using namespace std;
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <cctype>
#include <vector>
#include <set>
#include <cstdlib>
#include <map>
#include <queue>
//#include<initializer_list>
//#include <windows.h>
//#include <fstream>
//#include <conio.h>
#define MaxN 0x7fffffff
#define MinN -0x7fffffff
#define lson 2*k
#define rson 2*k+1
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn=105;
int Scan()//读入整数外挂.
{
    int res = 0, ch, flag = 0;

    if((ch = getchar()) == '-')             //判断正负
        flag = 1;

    else if(ch >= '0' && ch <= '9')           //得到完整的数
        res = ch - '0';
    while((ch = getchar()) >= '0' && ch <= '9' )
        res = res * 10 + ch - '0';
    return flag ? -res : res;
}
 void Out(int a)    //输出外挂
 {
     if(a>9)
         Out(a/10);
     putchar(a%10+'0');
 }
 int T;
 int N,M,S;
 int ans;
 bool g[105][105];
 bool vis[105];
 int Stap[15];
 vector<int> G[105];

 void init(int n)
 {
     ans=0;
     memset(g,false,sizeof(g));
     memset(vis,false,sizeof(vis));
     for(int i=1;i<=n;i++) G[i].clear();
 }
 void addedge(int u,int v)
 {
     if(u<v)G[u].push_back(v);
     else G[v].push_back(u);

     g[u][v]=true;
     g[v][u]=true;
 }
 void dfs(int root,int pre,int ceng)
 {
     Stap[ceng]=root;

     if(ceng==S)
     {
//        for(int i=1;i<=ceng;i++)
//        {
//            if(i==1)printf("%d",Stap[i]);
//            else printf("->%d",Stap[i]);
//        }
//        cout<<endl;
        ans++;
        return ;
     }

     for(int j=0;j<G[root].size();j++)
     {
         int v=G[root][j];
         if(vis[v])continue;
         if(v==pre)continue;

         bool flag=false;
         for(int now=ceng-1;now>=1;now--)
         {
             if(g[v][Stap[now]]==false)
             {
                 flag=true;
                 break;
             }
         }
         if(flag) continue;
         dfs(v,root,ceng+1);
     }

 }
int main()
{
#ifndef ONLINE_JUDGE
    freopen("coco.txt","r",stdin);
    freopen("lala.txt","w",stdout);
#endif
  scanf("%d",&T);
  while(T--)
  {
      scanf("%d%d%d",&N,&M,&S);

      init(N);
      int u,v;
      for(int i=1;i<=M;i++)
      {
          scanf("%d%d",&u,&v);
          addedge(u,v);
      }


      for(int i=1;i<=N;i++)
      {
          dfs(i,-1,1);
          vis[i]=true;
      }
      printf("%d\n",ans);

}

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值