1. 程式人生 > >ACM 2016 瀋陽區域賽 E - Counting Cliques (dfs)

ACM 2016 瀋陽區域賽 E - Counting Cliques (dfs)

HDU - 5952 

題目大意:

      一個團是一個完全圖,團內的任意兩個點之間都有邊相連。現在給你一個n個點m條邊的圖,問圖中大小為s的團有幾個

題解:

     資料範圍較小,直接dfs即可。

     搜的時候有一個技巧,每個點只存和它相連的並且比它大的點,這樣就不會有搜的重複問題了。

 

     訓練的時候想複雜了,以為是圖論相關問題,不敢寫搜尋,唉。。。。。

//#pragma comment(linker,"/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
#include<cstring>
#define ll long long
#define INF 1000000007
using namespace std;
int n,m,s,ans;
vector<int> e[200];
vector<int> sol;
bool b[200][200];
bool check(int x)
{
    int len=sol.size();
    for(int i=0;i<len;++i)
        if(b[sol[i]][x]==0)return 0;
    return 1;
}
void dfs(int tmp)
{
    int len=e[tmp].size();
    if(sol.size()==s)
    {
        ++ans;
        return;
    }
    for(int i=0;i<len;++i)
    {
        if(check(e[tmp][i]))
        {
            sol.push_back(e[tmp][i]);
            dfs(e[tmp][i]);
            sol.pop_back();
        }
    }
}
int main()
{
    //freopen("input.txt","r",stdin);
    int T,x,y;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&n,&m,&s);
        ans=0;
        memset(b,0,sizeof(b));
        for(int i=0;i<=n+10;++i)
            e[i].clear();
        for(int i=1;i<=m;++i)
        {
            scanf("%d%d",&x,&y);
            if(x>y)swap(x,y);
            e[x].push_back(y);
            b[x][y]=b[y][x]=1;
        }
        for(int i=1;i<=n;++i)
        {
            sol.clear();
            sol.push_back(i);
            dfs(i);
        }
        printf("%d\n",ans);
    }
    return 0;
}