zoukankan      html  css  js  c++  java
  • 树形dp——cf1332F【好题】

    思维题

    /*
    题意:给定一棵树,规定一种染色方案,要求有边相邻结点不能同时染色
        求所有边诱导子图的染色方案数之和
    转化:只有两个条件: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<<'
    ';
    } 
  • 相关阅读:
    我们工作为了什么
    为什么去国企(HP中华区总裁孙振耀退休感言)
    android中的所有activity间动画跳转
    [转]Eclipse进行可视化的GUI开发3大GUI插件
    用Monkey测试android程序
    大学之后拉开差距的原因
    dataset 和 datareader 区别
    曾经运行该线程的应用程序域已卸载。
    guid.tostring() 格式化指南
    vs 使用技巧
  • 原文地址:https://www.cnblogs.com/zsben991126/p/12633927.html
Copyright © 2011-2022 走看看