TZOJ6128: Graph Coloring(树形DP)

描述

Given an connected undirected graph with N vertices and N-1 edges,  you want to color all vertices with only 3 colors. 

Now, some vertices have been colored. you should color the remaining vertices and guarantee that each pair of directly connected vertices should not be the same color.

Please count the ways you can color all the remaining vertices.

输入

The first line contains two integers N and K (1<=K<=N<=100000),  N is the number of vertices and K is the number of colored vertices.

The next N-1 lines each has two integers u and v, describing the vertex u is directly connected with vertex v (1<=u, v<=N, u!=v).

The next K lines each has two integers x and c indicating that the vertex x (1<=x<=N) is colored with c (1<=c<=3).

输出

Output one integer s indicating the number of ways. Because the value is maybe very large, you just output s modulo 10^9+7.

样例输入

4 1
1 2
1 3
1 4
4 3

样例输出

8

 

最近在练图论,看到题目是一道图染色问题,便尝试一做。

题目大意是,给你一棵树,用三种颜色将这棵树染完,两两直接相连的节点颜色不能相同,求有多少种方案数?

刚开始我的思路是找规律,推公式,一通乱搞之后,跑了一遍深搜,结果连WA十几发,BUG修了很多次还是不能通过,这个时候我尝试换了下思路,一想有可能是树形DP。

我们可以尝试叶子节点向上往根节点染色,因为每个点只有三种染色方案(我们假设这三种颜色是红黄蓝),我们可以开一个二维数组dp[100010][3],dp[x][1]表示当前节点染成红色的方案数,dp[x][2]表示当前节点染成黄色的方案数,dp[x][3]表示当前节点染成蓝色节点的方案数。当前节点染成红色的方案数等于儿子节点染成黄色的方案数+染成蓝色的方案数的和的乘积,即dp[x][1]*=(dp[son][2]+dp[son][3]),染成其余两种颜色同理。这么一想豁然开朗,但代码敲完一交还是wrong answer,发现没开long long,改成long long 提交之后AC了。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e5+10;
 4 const int mod=1e9+7;
 5 typedef long long ll;
 6 vector<int> vec[maxn];
 7 int a[maxn];
 8 ll dp[maxn][4];
 9 
10 void dfs(int x,int fa,int root){
11     if(a[x]==0){
12         dp[x][1]=1;
13         dp[x][2]=1;
14         dp[x][3]=1;
15     }else if(a[x]==1){
16         dp[x][1]=1;
17         dp[x][2]=0;
18         dp[x][3]=0;
19     }else if(a[x]==2){
20         dp[x][1]=0;
21         dp[x][2]=1;
22         dp[x][3]=0;
23     }else if(a[x]==3){
24         dp[x][1]=0;
25         dp[x][2]=0;
26         dp[x][3]=1;
27     }
28     int hong=1,huang=1,lan=1;
29     for(int i=0;i<vec[x].size();++i){
30         int v=vec[x][i];
31         if(v==fa) continue;
32         dfs(v,x,root);
33         if(a[x]==0){
34             dp[x][1]=(dp[x][1]%mod)*((dp[v][2]%mod+dp[v][3]%mod)%mod)%mod;
35             dp[x][2]=(dp[x][2]%mod)*((dp[v][1]%mod+dp[v][3]%mod)%mod)%mod;
36             dp[x][3]=(dp[x][3]%mod)*((dp[v][1]%mod+dp[v][2]%mod)%mod)%mod;
37         }else{
38             if(a[x]==1){
39                 dp[x][1]=(dp[x][1]%mod)*((dp[v][2]%mod+dp[v][3]%mod)%mod)%mod;
40             }else if(a[x]==2){
41                 dp[x][2]=(dp[x][2]%mod)*((dp[v][1]%mod+dp[v][3]%mod)%mod)%mod;
42             }else if(a[x]==3){
43                 dp[x][3]=(dp[x][3]%mod)*((dp[v][1]%mod+dp[v][2]%mod)%mod)%mod;
44             }
45         }
46     } 
47 }
48 
49 int main(){
50     int n,k;
51     scanf("%d%d",&n,&k);
52     for(int i=1;i<=n-1;++i){
53         int x,y;
54         scanf("%d%d",&x,&y);
55         vec[x].push_back(y);
56         vec[y].push_back(x);
57     }
58     for(int i=1;i<=k;++i){
59         int x,col;
60         scanf("%d%d",&x,&col);
61         a[x]=col;
62     }
63     dfs(1,1,1);
64     printf("%lld\n",(dp[1][1]+dp[1][2]+dp[1][3])%mod);
65 }
上一篇:2021-7-29 Kefa and Park


下一篇:(牛哇牛哇)读取OBJ文件及其详解