思维题
/* 题意:给定一棵树,规定一种染色方案,要求有边相邻结点不能同时染色 求所有边诱导子图的染色方案数之和 转化:只有两个条件:1.右边相邻的结点不能同时染色 2.染色点至少要有一条边 f[u][0|1]表示不管u到父亲有没有边,该点不染色|染色,子树u的方案数 g[u]表示u和所有儿子之间没有边相连的方案数 f[u][0]=mul{ 2*f[v][0]+2*f[v][1]-g[v] } u不染色,v不染色时,(u,v)可有可无 u不染色,v染色时,那么v至少要有一条边连着,当(u,v)没有时,要减去g[v] f[u][1]=mul{ 2*f[v][0]+f[v][1]-g[v] } u染色,v不染色时,(u,v)可由可无 u染色,v染色时,(u,v)不可存在,且要减去g[v]的情况 g[u]=mul{ f[v][0]+f[v][1]-g[v] } (u,v)不存在,v可染色也可以不染色,但是染色的话要减去v和所有儿子无边的情况 */ #include<bits/stdc++.h> using namespace std; #define ll long long #define mod 998244353 #define N 500005 vector<int>G[N]; int n; ll f[N][2],g[N]; void dfs(int u,int pre){ for(auto v:G[u]) if(v!=pre)dfs(v,u); f[u][0]=f[u][1]=g[u]=1; for(auto v:G[u]) if(v!=pre){ f[u][0]=(2*f[v][0]%mod+2*f[v][1]%mod-g[v]+2*mod)%mod*f[u][0]%mod; f[u][1]=(2*f[v][0]%mod+f[v][1]-g[v]+2*mod)%mod*f[u][1]%mod; g[u]=(f[v][0]+f[v][1]-g[v]+2*mod)%mod*g[u]%mod; } } int main(){ cin>>n; for(int i=1;i<n;i++){ int u,v;cin>>u>>v; G[u].push_back(v); G[v].push_back(u); } dfs(1,1); //root不染色+root染色且和下面有边相连-都不染色 cout<<(f[1][0]+f[1][1]-g[1]-1+2*mod)%mod<<' '; }