题目大意
求树的最大独立集节点个数并判断最大独立集是否唯一
ps:树的最大独立集是指选出尽量多的点使得两两点之间没有边相连分析
如果不判断是否唯一这道题可以用贪心来做
但加了这个条件之后贪心就不好判断了
考虑动态规划的做法,用 dp[i][0] 和 dp[i][1] 分别表示以 i 节点为根的子树i 节点不选和选两种情况下的最大独立集节点数,转移方程就不用多说了。总结
这道题输入用的是字符串表示节点,所以一开始需要用map将字符串映射成一个数。
因为多组数据之间map没有初始化各种RE TLE WA了20+次,最后又因为Yes写成了YES WA了几发,心累代码
/*
求树的最大独立集节点个数并判断最大独立集是否唯一
*/
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<map>
#include<algorithm>
#include<set>
#include<stack>
using namespace std;
#define LL long long int
const int MAXN=2005;
map<string,int> mapp;
int n;
int index;
int tid[MAXN];//tid保存dfs序
int flag;//flag==1表示YES,最大独立集不唯一
int dp[MAXN][2];
int f[MAXN][2];//值为1表示有多种方案
int fa[MAXN];
struct Edge
{
int v;
int next;
}edge[MAXN*2];
int edgecount;
int head[MAXN];
void Init()
{
memset(head,-1,sizeof(head));
edgecount=0;
index=0;
flag=0;
memset(fa,0,sizeof(fa));
memset(dp,0,sizeof(dp));
memset(f,0,sizeof(f));
memset(tid,0,sizeof(tid));
}
void Add_edge(int u,int v)
{
edge[++edgecount].v=v;
edge[edgecount].next=head[u];
head[u]=edgecount;
}
void In()
{
mapp.clear();
int number=0;
string s;
string a,b;
cin>>s;
mapp[s]=++number;
for(int i=1;i<n;i++)
{
cin>>a>>b;//b是a的boss
if(mapp.count(a)==0)mapp[a]=++number;
if(mapp.count(b)==0)mapp[b]=++number;
Add_edge(mapp[b],mapp[a]);
// cout<<"edge: "<<mapp[b]<<" "<<mapp[a]<<endl;
}
}
void Dfs(int u)
{
tid[++index]=u;
for(int k=head[u];k!=-1;k=edge[k].next)
{
int v=edge[k].v;
if(v==fa[u])continue;
fa[v]=u;
Dfs(v);
}
}
void Dp()
{
for(int i=n;i>=1;i--)
{
int u=tid[i];
dp[u][1]=1;
dp[u][0]=0;
for(int k=head[u];k!=-1;k=edge[k].next)
{
int v=edge[k].v;
dp[u][1]+=dp[v][0];
dp[u][0]+=max(dp[v][0],dp[v][1]);
if(dp[v][0] > dp[v][1] && f[v][0]==1 ) f[u][0]=1;
else if(dp[v][1] > dp[v][0] && f[v][1]==1)f[u][0]=1;
else if(dp[v][0]==dp[v][1])f[u][0]=1;
if(f[v][0]==1)f[u][1]=1;
}
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
if(n==0)break;
Init();
In();
Dfs(1);
Dp();
printf("%d ",max(dp[1][0],dp[1][1]));
if(dp[1][0]>dp[1][1] && f[1][0]==1)printf("No\n");
else if(dp[1][1]>dp[1][0] && f[1][1]==1)printf("No\n");
else if(dp[1][1]==dp[1][0])printf("No\n");
else printf("Yes\n");//唯一
}
return 0;
}