POJ 3342 Party at Hali-Bula(树的最大独立集)

来源:互联网 发布:php 不识别utf8 编辑:程序博客网 时间:2024/06/06 08:54
  • 题目大意

    求树的最大独立集节点个数并判断最大独立集是否唯一
    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 intconst 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;}
原创粉丝点击