F1. Tree Cutting (Easy Version) ###K //K

题目链接:https://codeforces.ml/problemset/problem/1118/F1

题意:每个节点染上红或蓝或者不染色, 问有多少条边  使得该边删去后的两个连通块都不同时包含红和蓝色

思路:对于每个子树来说,要满足题意只能够是子树全部有红色,然后上半部分全部有蓝色这种情况,或者相反,

否则都是不含法的,所以当两种颜色都存在的时候 判断一下子树是不是有全部一种颜色 然后另外一种颜色为0

就能知道这是否是一条合法边, 如果有一种颜色没有的话就是n-1

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=3e5+10;
 4 const int mod=1e9+7;
 5 #define ll long long
 6 #define pi pair<int,int>
 7 #define fi first
 8 #define sc second
 9 #define pb push_back
10 int cnt[maxn][2];
11 int a[maxn];
12 vector<int>E[maxn];
13 int ans,n;
14 int cntr,cntb;
15 
16 void dfs(int u,int fa)
17 {
18     if(a[u]==1) cnt[u][1]++;
19     if(a[u]==2) cnt[u][0]++;
20     for(auto &v:E[u])
21     {
22         if(v==fa) continue;
23         dfs(v,u);
24         cnt[u][0]+=cnt[v][0];
25         cnt[u][1]+=cnt[v][1];
26         if(cnt[v][1]==cntr&&cnt[v][0]==0)
27             ans++;
28         if(cnt[v][0]==cntb&&cnt[v][1]==0)
29             ans++;
30     }
31 }
32 
33 
34 int main()
35 {
36     ios::sync_with_stdio(0);
37     cin.tie(0);
38     cin>>n;
39     for(int i=1;i<=n;i++) cin>>a[i],cntr+=a[i]==1,cntb+=a[i]==2;
40     for(int i=1;i<n;i++)
41     {
42         int x,y;
43         cin>>x>>y;
44         E[x].pb(y);
45         E[y].pb(x);
46     }
47     if(cntr&&cntb)
48         dfs(1,0);
49     else
50         ans=n-1;
51     cout<<ans<<'\n';
52 
53 
54 
55 
56 
57 }
View Code

 

posted @ 2021-02-21 23:07  canwinfor  阅读(77)  评论(0)    收藏  举报