hdu 5305 Friends

来源:互联网 发布:ubuntu mentohust下载 编辑:程序博客网 时间:2024/05/17 19:14

题意:

有n个人和m对朋友,现在要求每个人要有x个网友和x个实际的朋友,问有多少种方法可以满足这种要求。

分析:

因为最大的边只有28条,首先想到枚举边,但是2^28肯定TLE,所以我们可以枚举前面1半的边将其保存起来;然后枚举后面一半的边,查找满足要求的状态数。将查询的结果累加起来即可得到最终答案。

当有点的度数为奇数时,结果肯定是0。


以下附上代码:

#include <algorithm>#include <iostream>#include <cstdio>#include <vector>#include <map>using namespace std;struct Edge{  int u,v;};int t;int n,m;Edge a[50];int d[10];//degree int online[10];//每个人有多少个网友 bool second;int sum;map<vector<int>,int> Map; //int p[10];void input(){  scanf("%d%d",&n,&m);    for(int i = 0; i <= n; i++) d[i] = 0;    int u,v;  for(int i = 0; i < m; i++){    scanf("%d%d",&u,&v);    a[i].u = u;    a[i].v = v;    ++d[u]; ++d[v];  }}void dfs(int deep, int ter){  if(deep == ter){        if(!second){//前半部分枚举       for(int i = 1; i <= n; i++){//不插入非法状态         if(online[i] > d[i]/2)          return;      }      ++Map[vector<int>(online+1,online+n+1)];    }        if(second){//后半部分枚举             for(int i = 1; i <= n; i++)        p[i] = d[i]/2 - online[i];            if(Map.find(vector<int>(p+1,p+n+1)) != Map.end()){//查找状态         sum += Map[vector<int>(p+1,p+n+1)];              }    }    return;      }  //on  ++online[a[deep].u];  ++online[a[deep].v];  dfs(deep+1,ter);  --online[a[deep].u];  --online[a[deep].v];    //off  dfs(deep+1,ter); }bool check(){  for(int i = 1; i <= n; i++){    if(d[i] & 1)      return false;  }  return true;}void solve(){  Map.clear();  for(int i = 0; i <= n; i++) online[i] = 0;  sum = 0;  if(!check()){    printf("0\n");    return;  }    second = false;  dfs(0,m/2);  second = true;  dfs(m/2,m);  printf("%d\n",sum);}int main(){  scanf("%d",&t);  while(t--){    input();    solve();  }    return 0;}



0 0