一个有N个点M条边的图,球其中由S个点构成的团的个数。一个团是一个完全子图。
Input
第一行是测试点数。对于每个测试点,第一行包含3个整数N,M和S (N ≤ 100,M ≤ 1000,2 ≤ S ≤ 10),接下来的M行的每一行包含2整数u和v(1 ≤ u < v ≤ N),那就是说那里有一条边在u和v之间。保证顶点最大的度数不超过20。
Output
对于每个测试点,输出一个数表示图中大小为S的团的数量。
Sample Input
3
4 3 2
1 2
2 3
3 4
5 9 3
1 3
1 4
1 5
2 3
2 4
2 5
3 4
3 5
4 5
6 15 4
1 2
1 3
1 4
1 5
1 6
2 3
2 4
2 5
2 6
3 4
3 5
3 6
4 5
4 6
5 6
Sample Output
3
7
15
这个题要建出来单向边才行
因为是完全图遍历所以只存在一种关系
然而只要有一种可以到达就足够了…
还不用去重
骚的不行md
#include<bits/stdc++.h>
using namespace std;
template <class T> inline void in(T &x) {
T f = 1; char c; while ((c = getchar()) < '0' || c > '9') if (c == '-') f = -1;
x = c - '0';
while ((c = getchar()) >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0'; x *= f;
}
int mp[101][101],n,m,s,q,w,dan=0,bj[101],bjj[101];
vector<int>tu[101];
int linshi[11],lls[11];
map<string,int>mmp;
void dfs(int gen,int shendu)
{
if(shendu==s)
{
for(int a=1;a<=s-1;a++)
{
if(!mp[linshi[a]][gen])
{
return;
}
}
for(int a=1;a<s;a++)lls[a]=linshi[a];
lls[s]=gen;
/* string qw="";
sort(lls+1,lls+s+1);
for(int a=1;a<=s;a++)qw+=char(lls[a]);
if(mmp[qw])return;
mmp[qw]=1;*/
dan++;
return;
}
for(int a=1;a<shendu;a++)
{
if(!mp[linshi[a]][gen])
{
return;
}
}
bj[gen]=1;
linshi[shendu]=gen;
for(int a=0;a<tu[gen].size();a++)
{
int ww=tu[gen][a];
if(bj[ww])continue;
if(bjj[ww])continue;
dfs(ww,shendu+1);
}
bj[gen]=0;
linshi[shendu]=0;
}
int main()
{
int T;
in(T);
while(T--)
{
in(n),in(m),in(s);
dan=0;
mmp.clear();
memset(bjj,0,sizeof(bjj));
for(int a=1;a<=n;a++)tu[a].clear();
memset(mp,0,sizeof(mp));
for(int a=1;a<=m;a++)
{
in(q),in(w);
if(mp[q][w]||mp[w][q])continue;
mp[q][w]=mp[w][q]=1;
tu[q].push_back(w);
// tu[w].push_back(q);
}
for(int a=1;a<=n;a++)
{
bjj[a]=1;
dfs(a,1);
}
printf("%d\n",dan);
}
}