注意题目条件!!! 团问题 HDU 5952

题目大意:团的定义就是,团内的所有点,两两之间各有一条边,团的大小就是点的个数。现给你一个n个点,m条边的图。问,该图中有多少点的个数为s的团。

(题目保证每个点的度数不超过20,n<=100, m<=1000, s<=10)

思路:由于度数不超过20,那么最多就是C20取9,于是我们暴力枚举一下就好了。然后在代码中,我规定,邻接表G[U]里面的元素,都是u<v的。

//看看会不会爆int!数组会不会少了一维!
//取物问题一定要小心先手胜利的条件
#include <bits/stdc++.h>
using namespace std;
#pragma comment(linker,"/STACK:102400000,102400000")
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define haha printf("haha\n")
const int maxn = 500 + 5;
vector<int> G[maxn];
bool atlas[maxn][maxn];
int a[maxn];
int n, m, s;

int dfs(int u, int pos, int cnt, int s){
    if (cnt == s) {
        return 1;
    }
    int ans = 0;
    for (int i = pos; i < G[u].size(); i++){
        int v = G[u][i];
        bool flag = true;
        for (int j = 1; j <= cnt; j++){
            if (!atlas[a[j]][v]) {flag = false; break;}
        }
        if (!flag) continue;
        a[cnt + 1] = v;
        ans += dfs(u, i + 1, cnt + 1, s);
    }
    return ans;
}

int solve(){
    vector<int> ds;
    for (int i = 1; i <= n; i++){
        if (G[i].size() >= s - 1)  ds.pb(i);
    }
    int ans = 0;
    for (int i = 0; i < ds.size(); i++){
        int u = ds[i];
        a[1] = u;
        for (int j = 0; j < G[u].size(); j++){
            int v = G[u][j];
            a[2] = v;
            ans += dfs(u, j + 1, 2, s);
        }
    }
    return ans;
}

int main(){
    int t; cin >> t;
    while (t--){
        scanf("%d%d%d", &n, &m, &s);
        for (int i = 1; i <= n; i++) G[i].clear();
        memset(atlas, 0, sizeof(atlas));
        for (int i = 1; i <= m; i++){
            int u, v; scanf("%d%d", &u, &v);
            if (atlas[u][v]) continue;
            atlas[u][v] = 1, atlas[v][u] = 1;
            if (u > v) swap(u, v);
            G[u].pb(v);
        }
        printf("%d\n", solve());
    }
    return 0;
}
View Code

 

posted @ 2016-11-02 11:18  知る奇迹に  阅读(136)  评论(0编辑  收藏  举报