1. 程式人生 > >[USACO 2017DEC] Barn Painting

[USACO 2017DEC] Barn Painting

get sdi tar names col href n) c++ blank

[題目鏈接]

https://www.lydsy.com/JudgeOnline/problem.php?id=5141

[算法]

樹形DP

時間復雜度 : O(N)

[代碼]

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN = 1e5 + 10;
const int MAXC = 5; 
const int P = 1e9 + 7;

struct edge
{
    int to , nxt;
} e[MAXN 
<< 1]; int n , k , tot; int color[MAXN] , head[MAXN]; LL f[MAXN][MAXC]; template <typename T> inline void chkmax(T &x,T y) { x = max(x , y); } template <typename T> inline void chkmin(T &x,T y) { x = min(x , y); } template <typename T> inline void read(T &x) { T f
= 1; x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == -) f = -f; for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - 0; x *= f; } template <typename T> inline void update(T &x,T y) { x += y; x %= P; } template <typename T> inline void
mul(T &x,T y) { x = x * y; x %= P; } inline void addedge(int u,int v) { tot++; e[tot] = (edge){v , head[u]}; head[u] = tot; } inline LL dp(int u , int k , int fa) { if (f[u][k] != -1) return f[u][k]; f[u][k] = 1; for (int i = head[u]; i; i = e[i].nxt) { int v = e[i].to; if (v == fa) continue; if (color[v]) { if (color[v] == k) return f[u][k] = 0; else mul(f[u][k] , dp(v , color[v] , u)); } else { LL value = 0; for (int j = 1; j <= 3; j++) if (j != k) update(value , dp(v , j , u)); mul(f[u][k] , value); } } return f[u][k]; } int main() { read(n); read(k); for (int i = 1; i < n; i++) { int x , y; read(x); read(y); addedge(x , y); addedge(y , x); } for (int i = 1; i <= k; i++) { int b , c; read(b); read(c); color[b] = c; } for (int i = 1; i <= n; i++) f[i][1] = f[i][2] = f[i][3] = -1; if (color[1]) { printf("%lld\n",dp(1 , color[1] , -1)); } else { LL ans = 0; for (int i = 1; i <= 3; i++) update(ans , dp(1 , i , -1)); printf("%lld\n",ans); } return 0; }

[USACO 2017DEC] Barn Painting