zoukankan      html  css  js  c++  java
  • COJ1115(Special Operation)

    题目链接

    题目大意:给定一棵树,求最大点独立集中点的数目。

    这题昨晚一开始想到可以转化为求二部图的最大匹配来做,没估计复杂度,最后超时了。

    后来就考虑把树分成两部分,取结点较多的那部分作为结果,提交后WA。

    再后来,我考虑给树定一个根结点,然后分层,统计每层的结点数目,然后再转化为DP问题去做,相当于是分层DP,结果还是WA。

    昨天晚上躺在床上时,突然想到曾经听说过树形DP,难道这题正是?今天翻了下刘汝佳的白书,学习了下树形DP,然后果断AC。

    AC的代码
     1 #include <stdio.h>
     2 #include <vector> 
     3 #define MAX(a,b) ((a)>(b)?(a):(b))
     4 #define N 50000
     5 
     6 using namespace std;
     7 
     8 vector<int> g[N];
     9 
    10 int p[N],d[N],c[N],sums[N],sumgs[N],dmax,n;
    11 
    12 void read_tree()
    13 {
    14   int i,u,v;
    15   for(i=1;i<n;i++)
    16   {
    17     scanf("%d%d",&u,&v),u--,v--;
    18     g[u].push_back(v);
    19     g[v].push_back(u);
    20   }
    21 }
    22 void dfs(int u,int fa)
    23 {
    24   int i,v;
    25   d[u]=(fa==-1?0:d[fa]+1);
    26   dmax=MAX(dmax,d[u]);
    27   for(i=0;i<g[u].size();i++)
    28   {
    29     v=g[u][i];
    30     if(v!=fa) dfs(v,p[v]=u);
    31   }
    32 }
    33 void dp()
    34 {
    35   int i,j;
    36   for(i=dmax;i>=0;i--)
    37   {
    38     for(j=0;j<n;j++)
    39     {
    40       if(d[j]!=i) continue;
    41       c[j]=MAX(sums[j],sumgs[j]+1);
    42       if(i>0) sums[p[j]]+=c[j];
    43       if(i>1) sumgs[p[p[j]]]+=c[j];
    44     }
    45   }
    46 }
    47 int main()
    48 {
    49   int i;
    50   while(~scanf("%d",&n))
    51   {
    52     for(i=0;i<n;i++)  g[i].clear();
    53     memset(sums,0,sizeof(sums));
    54     memset(sumgs,0,sizeof(sumgs));
    55     dmax=0;
    56     read_tree();
    57     dfs(0,-1);
    58     dp();
    59     printf("%d\n",c[0]);
    60   }
    61   return 0;
    62 }
    超时的代码
     1 #include <stdio.h>
     2 #include <memory.h>
     3 #define N 50001
     4 int x[N],y[N],u[N],v[N],next[N],first[N],n;
     5 char vis[N];
     6 int con(int i,int j)
     7 {
     8   int e;
     9   for(e=first[i];e;e=next[e]) if(v[e]==j) return 1;
    10   return 0;
    11 }
    12 int path(int i)
    13 {
    14   int j;
    15   for(j=1;j<=n;j++)if((con(i,j)||con(j,i))&&!vis[j])
    16   {
    17     vis[j]=1;
    18     if(y[j]==-1 || path(y[j]))
    19     {
    20       x[i]=j;
    21       y[j]=i;
    22       return 1;
    23     }
    24   }
    25   return 0;
    26 }
    27 int maxmatch()
    28 {
    29   int i,cnt=0;
    30   for(i=1;i<=n;i++)if(x[i]==-1)
    31   {
    32     memset(vis,0,sizeof(vis));
    33     cnt+=path(i);
    34   }
    35   return cnt;
    36 }
    37 int main()
    38 {
    39   int i,j,e;
    40   freopen("in.txt","r",stdin);
    41   freopen("out.txt","w",stdout);
    42   while(~scanf("%d",&n))
    43   {
    44     memset(first,0,sizeof(first));
    45     for(e=1;e<n;e++)
    46     {
    47       scanf("%d%d",&u[e],&v[e]);
    48       next[e]=first[u[e]];
    49       first[u[e]]=e;
    50     }
    51     printf("%d\n",n-maxmatch()/2);
    52   }
    53   return 0;
    54 }
  • 相关阅读:
    WPF动态加载3D 放大-旋转-平移
    WPF窗口继承实现统一风格的自定义窗口
    桌面程序的其他实现方式----使用WPF窗体展现网页
    WPF 中自定义控件及其使用
    flask系列三之Jinja2模板
    Python模块学习
    利用Flask-SQLAlchemy提供的paginate()方法实现博客文章的分页显示
    Python利用flask sqlalchemy实现分页效果
    sqlalchemy和flask-sqlalchemy几种分页操作
    Python SQLAlchemy ORM示例
  • 原文地址:https://www.cnblogs.com/algorithms/p/2470710.html
Copyright © 2011-2022 走看看