CodeForces - 1118 F2 Tree Cutting

题目传送门

题解:

  先注意到一定存在k种颜色,切成k个块, 然后要求每个块内的颜色都一样,所以可以发现同一种颜色一定在同一个块内,故任意2个相同颜色的最短路劲上的点的颜色都是该颜色。

  我们可以先把任意相同颜色点对的路径上的点的颜色都染成这个颜色。 如果发现存在一个点是已经有颜色的话,那么答案一定为0。

  至于怎么颜色, 我们可以暴力往上跑,然后压缩路径,和并查集一样的道理,路过的点都染色且压缩。

  这样就完成了第一部分的处理,接下来就是树DP了。

  定义dp[ u ][ 0 ] 的含义是 以u为根的子树,且u还未被划入任意一种颜色的方案数。

    dp[ u ][ 1 ] 的含义是 以u为根的子树,且u已被划入任意一种颜色的方案数。

  那么对于有颜色的点来说,

    dp[u][0] = 0;

对于没有颜色的点来说:

代码:

/*
code by: zstu wxk
time: 2019/03/02
Tags: 树DP
Problem Link: http://codeforces.com/contest/1118/problem/F2
Solve: https://www.cnblogs.com/MingSD/p/10462228.html
*/
#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL _INF = 0xc0c0c0c0c0c0c0c0;
const LL mod = 998244353;
const int N = 3e5 + 100;
int n, k, deep[N], fa[N], col[N];
vector<int> vc[N], e1[N];
void dfs(int o, int u){
    deep[u] = deep[o] + 1;
    fa[u] = o;
    for(int v : e1[u]){
        if(v == o) continue;
        dfs(u, v);
    }
}
bool Link(int u, int v, int k){
    int tu = u, tv = v;
    while(u != v){
        if(deep[u] > deep[v]){
            u = fa[u];
            if(col[u] && col[u] != k) return false;
            col[u] = k;
        }
        else {
            v = fa[v];
            if(col[v] && col[v] != k) return false;
            col[v] = k;
        }
    }
    while(tu != u){
        int tt = fa[tu];
        fa[tu] = u;
        tu = tt;
    }
    while(tv != v){
        int tt = fa[tv];
        fa[tv] = v;
        tv = tt;
    }
    return true;
}
LL dp[N][2];
LL t1[N], t2[N], t3[N];
void DFS(int o, int u){
    for(int v : e1[u]){
        if(v == o) continue;
        DFS(u, v);
    }
    if(col[u]) {
        dp[u][0] = 0;
        dp[u][1] = 1;
        for(int v : e1[u]){
            if(v == o) continue;
            dp[u][1] = (dp[u][1] * (dp[v][0] + dp[v][1])) % mod;
        }
    }
    else {
        dp[u][0] = 1;
        dp[u][1] = 0;
        int k = e1[u].size();
        if(k){
            for(int i = 0; i < k; ++i){
                if(e1[u][i] == o)
                    t1[i+1] = 1;
                else {
                    t1[i+1] = dp[e1[u][i]][0] + dp[e1[u][i]][1];
                    dp[u][0] = dp[u][0] * t1[i+1] % mod;
                }
            }
            t2[0] = t3[k+1] = 1;
            for(int i = 1; i <= k; ++i)
                t2[i] = t1[i] * t2[i-1] % mod;
            for(int i = k; i >= 0; --i)
                t3[i] = t1[i] * t3[i+1] % mod;
            for(int i = 0; i < k; ++i){
                int v = e1[u][i];
                if(v == o) continue;
                dp[u][1] = (dp[u][1] + dp[v][1] * t2[i] % mod * t3[i+2] % mod) % mod;
            }
        }
    }
}
void Ac(){
    for(int i = 1, v; i <= n; ++i){
        scanf("%d", &v);
        if(v) vc[v].pb(i);
        col[i] = v;
    }
    for(int i = 1, u, v; i < n; ++i){
        scanf("%d%d", &u, &v);
        e1[u].pb(v);
        e1[v].pb(u);
    }
    dfs(0, 1);
    for(int i = 1; i <= n; ++i){
        for(int j = 1; j < vc[i].size(); ++j){
            if(!Link(vc[i][0],vc[i][j],i)) {
                puts("0");
                return ;
            }
        }
    }
    DFS(0, 1);
    printf("%I64d\n", dp[1][1]);
}
int main(){
    while(~scanf("%d%d", &n, &k)){
        Ac();
    }
    return 0;
}

    

原文地址:https://www.cnblogs.com/MingSD/p/10462228.html

时间: 2024-10-09 01:30:13

CodeForces - 1118 F2 Tree Cutting的相关文章

Codeforces Round #540 (Div. 3) F1. Tree Cutting (Easy Version) 【DFS】

任意门:http://codeforces.com/contest/1118/problem/F1 F1. Tree Cutting (Easy Version) time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output You are given an undirected tree of nn vertices. Some vert

3391: [Usaco2004 Dec]Tree Cutting网络破坏

3391: [Usaco2004 Dec]Tree Cutting网络破坏 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 76  Solved: 59[Submit][Status][Discuss] Description 约翰意识到贝茜建设网络花费了他巨额的经费,就把她解雇了.贝茜很愤怒,打算狠狠报 复.她打算破坏刚建成的约翰的网络.    约翰的网络是树形的,连接着N(1≤N≤10000)个牛棚.她打算切断某一个牛棚的电源,使和这个牛棚相连的

BZOJ 3391: [Usaco2004 Dec]Tree Cutting网络破坏( dfs )

因为是棵树 , 所以直接 dfs 就好了... ------------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #define rep( i , n ) for( int i = 0 ; i < n

贪心 Codeforces Round #300 A Cutting Banner

题目传送门 1 /* 2 贪心水题:首先,最少的个数为n最大的一位数字mx,因为需要用1累加得到mx, 3 接下来mx次循环,若是0,输出0:若是1,输出1,s[j]--: 4 注意:之前的0的要忽略 5 */ 6 #include <cstdio> 7 #include <iostream> 8 #include <cstring> 9 #include <string> 10 #include <algorithm> 11 #include

【HDU 5909】 Tree Cutting (树形依赖型DP+点分治)

Tree Cutting Problem Description Byteasar has a tree T with n vertices conveniently labeled with 1,2,...,n. Each vertex of the tree has an integer value vi. The value of a non-empty tree T is equal to v1⊕v2⊕...⊕vn, where ⊕ denotes bitwise-xor. Now fo

水题 Codeforces Round #300 A Cutting Banner

题目传送门 1 /* 2 水题:一开始看错题意,以为是任意切割,DFS来做:结果只是在中间切出一段来 3 判断是否余下的是 "CODEFORCES" :) 4 */ 5 #include <cstdio> 6 #include <iostream> 7 #include <cstring> 8 #include <string> 9 #include <algorithm> 10 #include <cmath>

Problem - D - Codeforces Fix a Tree

Problem - D - Codeforces  Fix a Tree 看完第一名的代码,顿然醒悟... 我可以把所有单独的点全部当成线,那么只有线和环. 如果全是线的话,直接线的条数-1,便是操作数. 如果有环和线,环被打开的同时,接入到线上.那就是线和环的总数-1. 如果只有环的话,把所有的环打开,互相接入,共需n次操作. #include <cstdio> #include <algorithm> using namespace std; const int maxn =

CodeForces - 383C Propagating tree(dfs + 线段树)

题目大意: 给出一棵树,树上每个节点都有权值,然后有两个操作. 1 x val 在结点x上加上一个值val,x的儿子加上 -val,x的儿子的儿子加上 - (-val),以此类推. 2 x 问x节点的值. 思路分析: 每个节点上加值都是给自己的儿子节点加,而且这个是颗树. 比如样例上的,如果你给node 1加一个值,那么五个节点都加. 再给node 2加个值,2的儿子节点也加了,之前给1加的值也要加到2号节点的儿子. 所以你会发现节点的儿子会存在一个从属的关系. 这样的话,我们可以把所有节点从新

poj 2378 Tree Cutting (树形dp)

Tree Cutting Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3910   Accepted: 2347 Description After Farmer John realized that Bessie had installed a "tree-shaped" network among his N (1 <= N <= 10,000) barns at an incredible