您的位置:首页 > 其它

【BZOJ 4455】 [Zjoi2016]小星星 容斥计数

2018-02-25 20:19 405 查看
dalao教导我们,看到计数想容斥……
卡常策略:枚举顺序、除去无效状态、(树结构)

#include <cstdio>
#include <cstring>
#include <algorithm>
typedef long long LL;
const int N=20;
LL f

;
int n,m,d

,full;
bool yeah
;
int st
,cnt;
struct V{
int to,next;
}c[N<<1];
int head
,t;
inline void add(int x,int y){
c[++t].to=y,c[t].next=head[x],head[x]=t;
}
inline void dfs(int x,int fa){
register int i,j,k;LL sum=0;
for(i=head[x];i;i=c[i].next)
if(c[i].to!=fa)
dfs(c[i].to,x);
for(i=1;i<=n;++i){
if(!yeah[i]){
f[x][i]=0;
continue;
}
f[x][i]=1;
for(j=head[x];j;j=c[j].next)
if(c[j].to!=fa){
sum=0;
for(k=1;k<=cnt;++k)
if(d[i][st[k]])
sum+=f[c[j].to][st[k]];
f[x][i]*=sum;
}
}
}
int main(){
scanf("%d%d",&n,&m);
full=(1<<n)-1;
int i,j,x,y;
for(i=1;i<=m;++i){
scanf("%d%d",&x,&y);
d[x][y]=d[y][x]=1;
}
for(i=1;i<n;++i){
scanf("%d%d",&x,&y);
add(x,y),add(y,x);
}
LL ans=0,sum;
for(i=1;i<=full;++i){
cnt=0,sum=0;
for(j=0;j<n;++j)
if(i&(1<<j))yeah[j+1]=true,st[++cnt]=j+1;
else yeah[j+1]=false;
dfs(1,0);
for(j=1;j<=n;++j)
sum+=f[1][j];
ans+=(((n-cnt)&1)?-1:1)*sum;
}
printf("%lld\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: