zoukankan      html  css  js  c++  java
  • Codeforces Round #630 -- F. Independent Set

    解法

    我们将独立子集中的点叫做染色点。
    题目其实就是在树上进行删边操作,使得没有相邻的染色点,且没有孤立的染色点。
    考虑树DP。对于每个节点,有3种状态,染色了,没有被染色且与儿子节点有连边,没有被染色且与所有儿子节点没连边(也就是孤立节点)。
    这样很容易进行转移
    (f[u][0]=prod_{v} (f[v][0]+f[v][1]+f[v][2])),这个点如果是孤立节点,就不和任何儿子连边,儿子状态也就任意
    剩余两种也类似,考虑连边不连边,在容斥一下就行了。
    需要注意的一点就是,在考虑当前节点不染色且与儿子连边的情况的时候,要考虑,这个节点和孤立儿子节点连边的话,是可以将儿子节点染色的。

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    
    const int maxn = 3e5;
    const ll mol = 998244353;
    ll f[maxn + 11][5];
    
    vector <int> edge[maxn + 11];
    ll add(ll a,ll b) { a += b; if (a >= mol) a -= mol; return a; }
    ll sub(ll a,ll b) { a -= b; if (a < 0) a += mol; return a; }
    
    void dfs(int x,int fa) {
    	ll tmp[10];
    	tmp[0] = tmp[1] = tmp[2] = 1;
    	for (auto v : edge[x]) {
    		if (v == fa) continue;
    		dfs(v , x);
    		tmp[0] = tmp[0] * add(add(f[v][0] , f[v][1]) , f[v][2]) % mol;
    		tmp[1] = tmp[1] * add(add(3 * f[v][0] % mol , 2 * f[v][1] % mol) , 2 * f[v][2] % mol) % mol;
    		tmp[2] = tmp[2] * add(add(2 * f[v][0] % mol , 2 * f[v][1] % mol) , f[v][2] % mol) % mol;
    	}
    	f[x][0] = tmp[0];
    	f[x][1] = sub(tmp[1] , tmp[0]);
    	f[x][2] = sub(tmp[2] , tmp[0]);
    } 
    
    int main(){ 
    	int n; scanf("%d",&n);
    	for (int i = 1; i < n; i++) {
    		int u,v;
    		scanf("%d %d",&u,&v);
    		edge[u].push_back(v);
    		edge[v].push_back(u);
    	} 
    	dfs(1 , 0);
    	printf("%lld
    " , sub(add(add(f[1][0] , f[1][1]) , f[1][2]) , 1));
    } 
    
    
  • 相关阅读:
    DB2数据库基础
    mysqldump 备份数据库脚本
    Windows Server 2012 R2 卸载IE浏览器
    mysqlpump 和 mysql_config_editor测试
    Linux 修改时区
    PowerShe 消息提示框测试
    Python使用libsvm的“ImportError: No module named svmutil”问题
    常见的机器学习&数据挖掘知识点
    [猜你喜欢]冠军“yes,boy!”分享,含竞赛源代
    用户人品预测大赛获奖团队分享
  • 原文地址:https://www.cnblogs.com/Embiid/p/12615781.html
Copyright © 2011-2022 走看看