Hdu 5952 Counting Cliques(2016沈阳网络赛)
2018-03-23 19:37
369 查看
点击打开链接
今天中午闲逛hzwer博客看到的一个题,开学断断续续的感冒整得我很难受...
题意:一个clique是指里面任意两个点之间都有边相连的图,给N个点M条边,求有多少个大小为S的clique。一开始读成了求联通块是什么鬼。。
那很显然要深搜,并在深搜的过程中要去check一下从后向前这么多个点是不是满足任意两个点都有边相连的。这段时间看了不少图论知识(忘得也好快)反正就是vector+map[][]这样的方式,然后本以为这样跑一遍就完事了,无向图对吧,看着数据这么小(我根本没有看时限)。。结果答案是不对的,譬如第一组样例是6,雾。。。
好吧这里要用到偏序问题(离散里的知识忘得更干净),既然是一个clique,那势必可以找出一条也是唯一一条形如k1<k2<k3<k4<ks这样的路径,因为很显然,如果在vector 加边时无序的话在搜索时从clique中的每个点进去是会重复的,想一想的确是显然的。所以就是从小到大加边呀,写就好了(我也不知道自己懂了没有,但就是这个意思)。图论真是奇妙
更:后来走下楼时想了想,这里的核心明明是因为避免重复,所以只建立单向边,并且从小的序号指向大的序号。偏序也是种解释方式。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<bitset>
#include<vector>
#include<algorithm>
#include<set>
#include<map>
using namespace std;
int n,m,t,s,cnt;
vector<int >G[105];
int ma[105][105],a[25];
void dfs(int k,int depth)
{
a[depth]=k;
if(depth==s)
{
cnt++;
return;
}
for(int i=0;i<G[k].size();i++)
{
int p=G[k][i];
bool ok=false;
for(int j=1;j<depth;j++)
{
if(!ma[p][a[j]])
{
ok=true;
break;
}
}
if(!ok)dfs(p,depth+1);
}
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&m,&s);
int p,q;
memset(ma,0,sizeof(ma));
for(int i=1;i<=m;i++)
{
scanf("%d%d",&p,&q);
if(p<q) G[p].push_back(q);
else G[q].push_back(p);
ma[p][q]=ma[q][p]=1;
}
cnt=0;
for(int i=1;i<=n;i++)
{
dfs(i,1);
}
printf("%d\n",cnt);
for(int i=1;i<=n;i++)G[i].clear();
}
}
今天中午闲逛hzwer博客看到的一个题,开学断断续续的感冒整得我很难受...
题意:一个clique是指里面任意两个点之间都有边相连的图,给N个点M条边,求有多少个大小为S的clique。一开始读成了求联通块是什么鬼。。
那很显然要深搜,并在深搜的过程中要去check一下从后向前这么多个点是不是满足任意两个点都有边相连的。这段时间看了不少图论知识(忘得也好快)反正就是vector+map[][]这样的方式,然后本以为这样跑一遍就完事了,无向图对吧,看着数据这么小(我根本没有看时限)。。结果答案是不对的,譬如第一组样例是6,雾。。。
好吧这里要用到偏序问题(离散里的知识忘得更干净),既然是一个clique,那势必可以找出一条也是唯一一条形如k1<k2<k3<k4<ks这样的路径,因为很显然,如果在vector 加边时无序的话在搜索时从clique中的每个点进去是会重复的,想一想的确是显然的。所以就是从小到大加边呀,写就好了(我也不知道自己懂了没有,但就是这个意思)。图论真是奇妙
更:后来走下楼时想了想,这里的核心明明是因为避免重复,所以只建立单向边,并且从小的序号指向大的序号。偏序也是种解释方式。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<bitset>
#include<vector>
#include<algorithm>
#include<set>
#include<map>
using namespace std;
int n,m,t,s,cnt;
vector<int >G[105];
int ma[105][105],a[25];
void dfs(int k,int depth)
{
a[depth]=k;
if(depth==s)
{
cnt++;
return;
}
for(int i=0;i<G[k].size();i++)
{
int p=G[k][i];
bool ok=false;
for(int j=1;j<depth;j++)
{
if(!ma[p][a[j]])
{
ok=true;
break;
}
}
if(!ok)dfs(p,depth+1);
}
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&m,&s);
int p,q;
memset(ma,0,sizeof(ma));
for(int i=1;i<=m;i++)
{
scanf("%d%d",&p,&q);
if(p<q) G[p].push_back(q);
else G[q].push_back(p);
ma[p][q]=ma[q][p]=1;
}
cnt=0;
for(int i=1;i<=n;i++)
{
dfs(i,1);
}
printf("%d\n",cnt);
for(int i=1;i<=n;i++)G[i].clear();
}
}
相关文章推荐
- 【2016-沈阳赛区现场赛-E】暴搜(Counting Cliques,hdu 5952)
- hdu 5952 Counting Cliques 暴力搜索 2016沈阳区域赛
- HDU 5898 odd-even number (数位DP) -2016 ICPC沈阳赛区网络赛
- hdu 5898 odd-even number 2016ACM/ICPC沈阳赛区网络赛1007
- HDU 5901 Count primes (2016 acm 沈阳网络赛)
- 【2016-沈阳赛区网络赛-I】区间DP(QSC and Master,hdu 5900)
- HDU 5894 hannnnah_j’s Biological Test (组合数学) -2016 ICPC沈阳赛区网络赛
- HDU5892~HDU5901 2016网络赛沈阳
- [2016ICPC 沈阳网络预选赛] HDU 5894 排列组合
- hdu 5898 - odd-even number (2016沈阳网络赛) - 数位dp
- hdu 5952 Counting Cliques 2016ACM/ICPC沈阳赛区现场赛E
- hdu 5900 - QSC and Master (2016沈阳网络赛)区间dp
- hdu 5892 List wants to travel 2016ACM/ICPC沈阳赛区网络赛1001
- HDU 5952 2016沈阳现场赛E Counting Cliques (团计数暴力)
- 【2016-沈阳赛区网络赛-G】记忆化搜索,数位DP(odd-even number,hdu 5898)
- hdu 5893 List wants to travel 2016ACM/ICPC沈阳赛区网络赛1002
- HDU 5901 Count primes (1e11内的素数个数) -2016 ICPC沈阳赛区网络赛
- hdu5894 hannnnah_j’s Biological Test(2016 acm/icpc 沈阳网络赛,组合数学)
- hdu(2016’12)- 网络同步赛
- hdu 5883 The Best Path 2016ACM/ICPC青岛赛区网络赛1006