LINK:Independent Set
题目定义了 独立集和边诱导子图。然而和题目没有多少关系。
给出一棵树 求(sum_{E' eq varnothing,E'subset E}w(G(E')))
(w(E))表示一张E的独立集的个数。E'为边诱导子图.
在这棵树中 边诱导子图的个数为(2^{n-1}-1)除掉空集.
还是利用儿子来表示每一条边选了没有 这样可以实现断边的问题。
所以有由于此时独立集的数量只要在知道集合的最大独立集个数时才能O(1)求出 但是个数有很多 还是考虑dp求出数量。
f[i][1/0][1/0]表示i与父亲相连的边在不在诱导子图中0/1,在不在独立集中1/0.
考虑 (f[i][1][1]=Pi(f[tn][0][1]+f[tn][0][0]+f[tn][1][0]) tnin son[i])
(f[i][1][0]=Pi(f[tn][0][1]+f[tn][0][0]+f[tn][1][0]+f[tn][1][1]) tnin son[i])
(f[i][0][1]=Pi(f[tn][0][1]+f[tn][0][0]+f[tn][1][0])-Pi(f[tn][0][1]+f[tn][0][0]) tnin son[i])
(f[i][0][0]=Pi(f[tn][0][1]+f[tn][0][0]+f[tn][1][0]+f[tn][1][1]) tnin 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;
}