hdu 4997 状压dp

来源:互联网 发布:电脑屏幕视频录制软件 编辑:程序博客网 时间:2024/05/29 16:28
/************************************************************************* > File Name: hdu4997.cpp > Author: TechMonster > Mail: 928221136@qq.com > Created Time: 六  7/ 9 12:15:10 2016 ************************************************************************/#include<stdio.h>#include<string.h>#include<ctype.h>#include<string>#include<math.h>#include<map>#include<set>#include<vector>#include<queue>#include<algorithm>using namespace std;template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b>a)a = b; }template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b<a)a = b; }#define ls (o<<1)#define MS(x,y) memset(x,y,sizeof(x))#define MC(x, y) memcpy(x, y, sizeof(x))typedef long long LL;const int N = 1030;const int M = 1e9+7;int mp[10][10];int e[N],con[N],meth[N][N],bico[N];int n,m;int getlow(int &sta){for(int i = 0; i < n; ++i)if(sta & 1<<i) return i;return -1;}void calc(int &sta){int low = getlow(sta);e[sta] = e[sta ^ 1<<low];for(int i = 0; i < n; ++i)if(!mp[i][low] && sta & 1<<i) e[sta]++;con[sta] = (1ll<<e[sta])%M;int rs = sta ^ 1<<low,ns;if(rs) for(int i = rs-1&rs;; i = i-1&rs){ns = i ^ 1<<low;con[sta] -= (LL)con[ns]*((1ll<<e[sta^ns])%M)%M;con[sta] %= M;if(!i) break;}meth[0][sta] = 1;for(int s = sta-1&sta; s; s = s-1&sta){int &t = meth[s][sta^s] = 0;rs = s-(s&-s);for(int i = rs;; i = i-1&rs){ns = i^(s&-s);t += (LL)meth[s^ns][sta^s]*con[ns]%M*(e[sta^ns^s]-e[ns]-e[sta^s])%M;t %= M;if(!i) break;}}bico[sta] = con[sta];rs = sta ^ 1<<low;if(rs) for(int i = rs-1&rs;; i = i-1&rs){ns = i ^ 1<<low;bico[sta] -= (LL)bico[ns]*meth[sta^ns][ns]%M;bico[sta] %= M;if(!i) break;}}void solve(){int u,v;scanf("%d%d",&n,&m);MS(mp,0);for(int i = 0; i < n; ++i) mp[i][i] = 1;for(int i = 0; i < m; ++i){scanf("%d%d",&u,&v);u--,v--;mp[u][v] = mp[v][u] = 1;}int top = 1<<n;for(int i = 1; i < top; ++i)calc(i);//printf("%d:%d %d %d\n",i,e[i],con[i],bico[i]);printf("%d\n",(bico[top-1]%M+M)%M);}int main(){int T;scanf("%d",&T);while(T--)solve();return 0;}

2 0
原创粉丝点击