bzoj4455: [Zjoi2016]小星星
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<queue>
#include<cmath>
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
const int N=18;
typedef long long LL;
using namespace std;
int n,m,a[N][N],b[N];
template<typename T>void read(T &x) {
char ch=getchar(); x=0; T f=1;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=-1,ch=getchar();
for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}
int ecnt,fir[N],nxt[N<<2],to[N<<2];
void add(int u,int v) {
nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v;
nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u;
}
LL dp[N][N],ans;
void dfs(int x,int fa) {
for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa)
dfs(to[i],x);
For(i,1,b[0]) {
dp[x][i]=1;
for(int j=fir[x];j;j=nxt[j]) if(to[j]!=fa) {
LL tp=0;
For(k,1,b[0]) if(a[b[i]][b[k]])
tp+=dp[to[j]][k];
dp[x][i]*=tp; if(!dp[x][i]) break;
}
}
}
int main() {
#ifdef DEBUG
freopen(".in","r",stdin);
freopen(".out","w",stdout);
#endif
read(n); read(m);
For(i,1,m) {
int x,y;
read(x); read(y);
a[x][y]=a[y][x]=1;
}
For(i,2,n) {
int x,y;
read(x); read(y);
add(x,y);
}
int nn=(1<<n);
For(i,1,nn-1){
int sum=n; LL w=0; b[0]=0;
For(j,1,n) if(i&(1<<(j-1))) { sum--; b[++b[0]]=j; }
dfs(1,0);
For(i,1,b[0]) w+=dp[1][i];
if(sum&1) ans-=w;
else ans+=w;
}
printf("%lld\n",ans);
return 0;
}
/*
4 3
1 2
1 3
1 4
4 1
4 2
4 3
*/