hdu 5952 Counting Cliques(dfs优化) 2016ACM/ICPC亚洲区沈阳站

来源:互联网 发布:淘宝客户信誉查询 编辑:程序博客网 时间:2024/05/16 10:05

题目链接;点击打开链接

题目大意:给一n个点m条边的图,找一个有s个顶点的完全子图。

什么是完全子图?即子图中每个点到其他点都有一条边相连

思路:

对于每个s点完全子图,如果i点在子图中,那么就枚举与i有边的其他点,每加入一个点,就判断一下是否和其他已加入的点有边,如果是就可以加入,否则不能加。
  最后再优化一下:防止重复计算,对于搜过点从图中删去。这样就不用标记判重了

#include <cstdio>#include <cstring>#include <cmath>#include <iostream>#include<vector>#include<stack>#include<iostream>using namespace std;const int maxn=120;int n,m,s;int dis[maxn][maxn];int ans;int Stack[maxn];int top;vector<int>g[maxn];//每个点连向哪几个点void init(){ans=0;memset(dis,0,sizeof dis);for(int i=1;i<=n;i++)g[i].clear();memset(Stack,0,sizeof Stack);top=0;}bool check(int x){for(int i=0;i<top;i++){if(!dis[Stack[i]][x]&&!dis[x][Stack[i]])return false;}return true;}void dfs(int u,int id){if(top==s){ans++;return ;}if(g[u].size()-id<s-top||id>=g[u].size())//剪枝return;if(check(g[u][id]))//如果加入该元素的话{Stack[top++]=g[u][id];dfs(u,id+1);top--;}dfs(u,id+1);}int main(){int t;scanf("%d",&t);while(t--){scanf("%d%d%d",&n,&m,&s);init();for(int i=0;i<m;i++){int u,v;scanf("%d%d",&u,&v);dis[u][v]=dis[v][u]=1;g[u].push_back(v);g[v].push_back(u);}for(int i=1;i<=n;i++){Stack[top++]=i;dfs(i,0);top--;for(int j=1;j<=n;j++){dis[i][j]=dis[j][i]=0;}}printf("%d\n",ans);}return 0;}/*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*/


阅读全文
0 0
原创粉丝点击