您的位置:首页 > 产品设计 > UI/UE

HDU - 5952 Counting Cliques(图上暴力搜索+技巧剪枝)

2017-10-19 21:56 645 查看

题目大意:

给你一个无向图,100个点1000条边,问你这个图中有多少个小于等于s的点集可以组成一个完全图。s<=10

分析:

其实是想复杂了,真的只需要暴力搜索就可以了。分析复杂度的时候不应该是考虑每个点都有20个出边,所以是10的20次方。而应该是考虑只有1000条边,所以我最多才枚举1000条边,100个点,再加上每次判断最多1e6的时间复杂度,再加一些剪枝,肯定不会超时的。

然后就是如何避免搜索出重复的呢,我的考虑是,用邻接表存边,而且我只存起点标号小于终点标号的边,这样在枚举的过程中我既避免了重复计算,又完成了剪枝。还降低了代码复杂度。

代码:

#include<bits/stdc++.h>
using namespace std;
int con[105][105],ans,n,m,s;
vector<int>a[105];
int now[20];
void dfs(int x)
{
if(x==s-1)
{
ans++;
return;
}
int pre=now[x];
for(int i=0;i<a[pre].size();i++)
{
int flag=1;
for(int j=0;j<=x;j++)
{
if(con[a[pre][i]][now[j]]==0)
{
flag=0;break;
}
}
if(flag==1)
{
now[x+1]=a[pre][i];
dfs(x+1);
}
}
}

int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(con,0,sizeof(con));
for(int i=0;i<105;i++)a[i].clear();
scanf("%d%d%d",&n,&m,&s);
for(int i=0;i<m;i++)
{
int temp_f,temp_t;
scanf("%d%d",&temp_f,&temp_t);
con[temp_f][temp_t]=1;
con[temp_t][temp_f]=1;
if(temp_t<temp_f){int temp=temp_f;temp_f=temp_t;temp_t=temp;}
a[temp_f].push_back(temp_t);
}
ans=0;
memset(now,0,sizeof(now));
for(int i=1;i<=n;i++)
{
now[0]=i;
dfs(0);
}
printf("%d\n",ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息