题意:给出一个无向图, 问其中的结点数为s的完全图有多少个
思路:我最初的思路是不管重复直接搜,然后最后答案除一个s的阶乘, 但是超时, 后来发现其实可以不算重复的, 就是将搜索有序化,
举个例子: 你现在有4个数 4 2 3 1, 那么你要选出其中3个, 那么选择的顺序就是 4 2 3 , 4 2 1, 4 3 2, 2 3 1, 那么两个数能不能选, 就看是否有边存在,当然因为是找完全图, 所以还要判定和之前所选出来的结点是不是都有边相连.
#include <cstring>
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cctype>
#include <queue>
#include <map>
#include <set>
#include <vector>
using namespace std;
const int qq = 1000 + 10;
int link[qq][qq];
int node[105];
int n, m, k, sum;
vector<int> v[105];
void dfs(int u, int cnt){
if(cnt == k){
sum++;
return;
}
int len = v[u].size();
for(int i = 0; i < len; ++i){
int to = v[u][i];
bool f = true;
for(int j = 1; j < cnt; ++j)
if(!link[node[j]][to]){
f = false;
break;
}
if(f){
node[cnt+1] = to;
dfs(to, cnt + 1);
node[cnt+1] = 0;
}
}
}
int main(){
int t; scanf("%d", &t);
while(t--){
memset(link, 0, sizeof(link));
scanf("%d%d%d", &n, &m, &k);
int x, y;
for(int i = 0; i < m; ++i){
scanf("%d%d", &x, &y);
if(x > y) swap(x, y);
link[x][y] = 1;
v[x].push_back(y);
}
sum = 0;
for(int i = 1; i <= n; ++i){
int cnt = 1;
node[cnt] = i;
dfs(i, cnt);
}
printf("%d\n", sum);
for(int i = 1; i <= n; ++i) v[i].clear();
}
return 0;
}
下面是超时的代码. 我不知道为什么除s的阶乘是对的, 模模糊糊觉得是, 写上去貌似还是对的, 希望路过的巨巨能帮忙证明一下
#include <cstring>
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cctype>
#include <queue>
#include <map>
#include <set>
#include <vector>
using namespace std;
const int qq = 1000 + 10;
int link[qq][qq];
int node[105];
int n, m, k, sum;
vector<int> v[105];
void dfs(int u, int cnt){
if(cnt == k){
// for(int i = 1;i <= cnt ; ++i)
// printf("%d ", node[i]);
// printf("\n");
sum++;
return;
}
int len = v[u].size();
for(int i = 0; i < len; ++i){
int to = v[u][i];
bool f = true;
for(int j = 1; j < cnt; ++j)
if(!link[node[j]][to]){
f = false;
break;
}
if(f){
node[cnt+1] = to;
dfs(to, cnt + 1);
node[cnt+1] = 0;
}
}
}
int fun(int a){
int res = 1;
for(int i = 2; i <= a; ++i)
res *= i;
return res;
}
int main(){
int t; scanf("%d", &t);
while(t--){
memset(link, 0, sizeof(link));
scanf("%d%d%d", &n, &m, &k);
int x, y;
for(int i = 0; i < m; ++i){
scanf("%d%d", &x, &y);
link[x][y] = link[y][x] = 1;
v[x].push_back(y);
v[y].push_back(x);
}
sum = 0;
for(int i = 1; i <= n; ++i){
int cnt = 1;
node[cnt] = i;
dfs(i, cnt);
}
printf("%d\n", sum/fun(k));
for(int i = 1; i <= n; ++i) v[i].clear();
}
return 0;
}