NC19914. [CQOI2009]叶子的染色
描述
输入描述
第一行包含两个正整数m, n,其中n是叶子的个数,m是结点总数。结点编号为1,2,…,m,其中编号1,2,… ,n是叶子。
以下n行每行一个0或1的整数(0表示黑色,1表示白色),依次为c[1],c[2],…,c[n]。
以下m-1行每行两个整数a,b(1 ≤ a < b ≤ m),表示结点a和b 有边相连。
输出描述
仅一个数,即着色结点数的最小值。
示例1
输入:
5 3 0 1 0 1 4 2 5 4 5 3 5
输出:
2
C++(g++ 7.5.0) 解法, 执行用时: 12ms, 内存消耗: 5628K, 提交时间: 2023-07-11 17:07:31
#include<bits/stdc++.h> using namespace std; const int N=2e5+10; int n,m; int arr[N],dp[N][3]; vector<int> to[N]; void dfs(int u,int fa){ if(u<=m){ dp[u][arr[u]]=1; dp[u][1-arr[u]]=1e9; return; } dp[u][0]=dp[u][1]=1; for(auto v:to[u]){ if(v==fa) continue; dfs(v,u); dp[u][1]+=min(dp[v][1]-1,dp[v][0]); dp[u][0]+=min(dp[v][0]-1,dp[v][1]); } } void solve(){ cin>>n>>m; for(int i=1;i<=m;i++) cin>>arr[i]; for(int i=1;i<n;i++){ int a,b; cin>>a>>b; to[a].push_back(b); to[b].push_back(a); } int ans=1e9; for(int i=m+1;i<=m+1;i++){ dfs(i,0); ans=min(dp[i][0],dp[i][1]); } cout<<ans<<"\n"; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int t=1; // cin>>t; while(t--) solve(); }
C++14(g++5.4) 解法, 执行用时: 10ms, 内存消耗: 3168K, 提交时间: 2020-01-30 11:22:23
#include<bits/stdc++.h> using namespace std; #define see(x) cerr<<(#x)<<"="<<x<<endl; typedef long long ll; const int N=1e5+100; vector<int>edge[N]; int dp[N][2]; void dfs(int x,int fa) { for(auto v:edge[x]) if(v!=fa) { dfs(v,x); dp[x][0]+=min(dp[v][0]-1,dp[v][1]); dp[x][1]+=min(dp[v][1]-1,dp[v][0]); } } int main() { int n,m; cin>>n>>m; for(int i=1;i<=n;i++) dp[i][1]=dp[i][0]=1; for(int i=1,x;i<=m;i++) { scanf("%d",&x); dp[i][!x]=1e9; } for(int i=1,u,v;i<n;i++) { scanf("%d%d",&u,&v); edge[u].push_back(v); edge[v].push_back(u); } dfs(n,0); cout<<min(dp[n][0],dp[n][1]); }
C++11(clang++ 3.9) 解法, 执行用时: 34ms, 内存消耗: 24556K, 提交时间: 2020-04-03 14:36:01
#include<bits/stdc++.h> using namespace std; const int N=1e6+100; vector<int>G[N]; int dp[N][2],col[N]; int m,n; void dfs(int x,int fa) { if(x<=n) { dp[x][col[x]]=1; dp[x][col[x]^1]=0x3f3f3f3f; return; } dp[x][0]=dp[x][1]=1; for(int v:G[x]) { if(v==fa) continue; dfs(v,x); dp[x][0]+=min(dp[v][0]-1,dp[v][1]); dp[x][1]+=min(dp[v][1]-1,dp[v][0]); } } int main() { cin>>m>>n; for(int i=1;i<=n;i++) cin>>col[i]; for(int i=1;i<m;i++) { int x,y; cin>>x>>y; G[x].push_back(y); G[y].push_back(x); } dfs(m,0); cout<<min(dp[m][0],dp[m][1])<<endl; return 0; }