CF R 630 div2 1332 F Independent Set
LINK:Independent Set
题目定义了 独立集和边诱导子图。然而和题目没有多少关系。
给出一棵树 求∑E′≠∅,E′⊂Ew(G(E′))
w(E)表示一张E的独立集的个数。E'为边诱导子图.
在这棵树中 边诱导子图的个数为2n−1−1除掉空集.
还是利用儿子来表示每一条边选了没有 这样可以实现断边的问题。
所以有由于此时独立集的数量只要在知道集合的最大独立集个数时才能O(1)求出 但是个数有很多 还是考虑dp求出数量。
f[i][1/0][1/0]表示i与父亲相连的边在不在诱导子图中0/1,在不在独立集中1/0.
考虑 f[i][1][1]=Π(f[tn][0][1]+f[tn][0][0]+f[tn][1][0])tn∈son[i]
f[i][1][0]=Π(f[tn][0][1]+f[tn][0][0]+f[tn][1][0]+f[tn][1][1])tn∈son[i]
f[i][0][1]=Π(f[tn][0][1]+f[tn][0][0]+f[tn][1][0])−Π(f[tn][0][1]+f[tn][0][0])tn∈son[i]
f[i][0][0]=Π(f[tn][0][1]+f[tn][0][0]+f[tn][1][0]+f[tn][1][1])tn∈son[i]
转移确实不难 但是状态还是很难构思出来的。
const ll MAXN=300010;
ll n,maxx,m,len;
ll lin[MAXN],ver[MAXN<<1],nex[MAXN<<1];
ll f[MAXN][2][2];
inline void add(ll x,ll y)
{
ver[++len]=y;
nex[len]=lin[x];
lin[x]=len;
}
inline void dp(ll x,ll fa)
{
f[x][1][1]=1;
f[x][1][0]=1;
ll sum=1;
go(x)
{
if(tn==fa)continue;
dp(tn,x);
f[x][1][1]=f[x][1][1]*(f[tn][0][1]+f[tn][0][0]+f[tn][1][0])%mod;
f[x][1][0]=f[x][1][0]*(f[tn][0][1]+f[tn][0][0]+f[tn][1][0]+f[tn][1][1])%mod;
sum=sum*(f[tn][0][1]+f[tn][0][0])%mod;
}
f[x][0][1]=(f[x][1][1]-sum)%mod;
f[x][0][0]=f[x][1][0];
}
signed main()
{
freopen("1.in","r",stdin);
get(n);
rep(1,n-1,i)
{
ll get(x);ll get(y);
add(x,y);add(y,x);
}
dp(1,0);putl(((f[1][0][1]+f[1][0][0]-1)%mod+mod)%mod);
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步