http://acm.hdu.edu.cn/showproblem.php?pid=5925
题意:给你一个无向完全图,求指定大小s个点的完全图子图的个数。
解法:单向建边顺序遍历,避免重复。
#include<stdio.h> #include<string.h> #include<math.h> #include<queue> #include<algorithm> #include<iostream> #include<map> #define inf 0x3f3f3f3f #define ll long long #define maxx 5000000 #define mod 2147493647//注意这是一个ll型的数,会爆int using namespace std; int vis[109][109]; int temp[109]; int n , m , s ; int ans , flag; int head[109]; struct node{ int to , next ; }g[2009]; int cnt; void add(int u , int v) { g[cnt].to = v ; g[cnt].next = head[u]; head[u] = cnt++ ; } void dfs(int u , int num) { if(num == s)//如果符合条件的点数等于指定点数,计数。 { ans++; return ; } temp[num] = u ;//将该点加入集合 for(int i = head[u] ; i != -1 ; i = g[i].next)//dfs0遍历 { int v = g[i].to ; flag = 1 ; for(int j = 1 ; j < num ; j++)//判断该点是否与已经加入集合的点构成完全图 { if(!vis[v][temp[j]])//与集合内的点不能构成完全图 { flag = 0 ; break; } } if(flag)//能构成完全图 { dfs(v , num+1);//加入该点,进入下一个点 } } } void init() { memset(head , -1 , sizeof(head)); cnt = 0 ; ans = 0 ; memset(vis , 0 , sizeof(vis)); } int main() { int t ; scanf("%d" , &t); while(t--) { init(); scanf("%d%d%d" , &n , &m , &s); for(int i = 0 ; i < m ; i++) { int u , v ; scanf("%d%d" , &u , &v); if(u > v) swap(u , v);//单向顺序 add(u , v); vis[u][v] = vis[v][u] = 1 ;//两点有边相连 } for(int i = 1 ; i <= n ; i++)//遍历每一个点 { dfs(i , 1); } cout << ans << endl; } return 0 ; }