题意:
给你一棵树,用黑白染色,求最少的染黑的个数,使得每个白点都与且只与1个黑点相连。
题解:
dp[x][f]表示将x染成f状态最少需要染多少黑点,f有三种状态:0,1,2
0:表示该点为白色,且他的所有儿子都为白色。
1:表示该点为黑色。
2:表示该点为白色,且他有一个儿子为黑色。
dp[x][1]=sigma(min(dp[son(x)][1],dp[son(x)][0]));
dp[x][0]=sigma(dp[son(x)][2]);
dp[x][2]=min(dp[son(xi)][1]+sigma(dp[son(!xi)][2]));//xi为枚举的某个染黑的儿子,!xi为剩下的儿子。
More:
开始题目看错了,看错每个白点至少和一个黑点相连,这样的话状态转移为:
dp[x][1]=sigma(min(dp[son(x)][1],dp[son(x)][0],dp[son(x)][2]));
dp[x][0]=sigma(dp[son(x)][2]);
dp[x][2]=min(dp[son(xi)][1]+sigma(min(dp[son(!xi)][2],dp[son(!xi)][2])));//xi为枚举的某个染黑的儿子,!xi为剩下的儿子。
代码:
#include <stdio.h>
#include <memory.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;
#define N 1005
#define INF 100000
vector<int> tr[N],t[N];
int dp[N][4];
int father[N];
bool visited[N];
map<int ,int > mp;
void build_tree(int x)
{
int i;
visited[x]=1;
for(i=0;i<t[x].size();i++)
if (!visited[t[x][i]])
{
father[t[x][i]]=x;
build_tree(t[x][i]);
}
}
int min(int x,int y)
{
if (x<y) return x;
else return y;
}
int tree_dp(int x,int f)
{
if (dp[x][f]!=-1) return dp[x][f];
int i,j,sum;
if (f==1)
{
sum=0;
for(i=0;i<tr[x].size();i++)
sum+= min( tree_dp(tr[x][i],1),tree_dp(tr[x][i],0) );
dp[x][f]=sum+1;
}
if (f==0)
{
sum=0;
for(j=0;j<tr[x].size();j++)
sum+=tree_dp(tr[x][j],2);
dp[x][f]=sum;
}
if (f==2)
{
sum=0;
int ans=INF;
for(i=0;i<tr[x].size();i++)
{
sum=tree_dp(tr[x][i],1);
for(j=0;j<tr[x].size();j++)
if (i!=j)
sum+=tree_dp(tr[x][j],2);
if (sum<ans) ans=sum;
}
dp[x][f]=ans;
}
return dp[x][f];
}
int main()
{
int n,i,j,x,y;
while(cin>>n)
{
mp.clear();
int cnt=0;
if (n==0) break;
for(i=1;i<=n+1;i++)
t[i].clear();
for(i=1;i<=n;i++)
{
cin>>x>>y;
if ( mp.find(x)==mp.end() ) mp[x]=++cnt;
if ( mp.find(y)==mp.end() ) mp[y]=++cnt;
x=mp[x];y=mp[y];
t[x].push_back(y);
t[y].push_back(x);
}
n++;
father[1]=0;
memset(visited,0,sizeof(visited));
build_tree(1);
for(i=1;i<=n;i++)
{
tr[i].clear();
for(j=0;j<t[i].size();j++)
if (t[i][j]!=father[i])
tr[i].push_back(t[i][j]);
}
memset(dp,-1,sizeof(dp));
int ans=min(
tree_dp(1,2),
tree_dp(1,1));
cout<<ans<<endl;
}
}