HDU5952(66/600)

一个有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);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值