一道经典的树型DP入门题。dp[u][0/1]表示u点不选或选时以u为根的子树最多能选择的点数。

题目给的有向有环图可以看作森林,注意不是树,因为题目没有说图是连通的

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 1111
#define MAXM 1111*1111
struct Edge{
int v,next;
}edge[MAXM];
int NE,head[MAXN];
void addEdge(int u,int v){
edge[NE].v=v; edge[NE].next=head[u]; head[u]=NE++;
}
int d[MAXN][];
int dfs(int u,int k,int fa){
if(d[u][k]!=-) return d[u][k];
int res=k;
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(v==fa) continue;
if(k) res+=dfs(v,,u);
else res+=max(dfs(v,,u),dfs(v,,u));
}
return d[u][k]=res;
}
int par[MAXN];
int Find(int a){
while(a!=par[a]){
par[a]=par[par[a]];
a=par[a];
}
return a;
}
void Union(int a,int b){
int pa=Find(a),pb=Find(b);
if(pa==pb) return;
par[pb]=pa;
}
int main(){
int t,n,m,a,b;
scanf("%d",&t);
for(int cse=; cse<=t; ++cse){
NE=;
memset(head,-,sizeof(head));
scanf("%d%d",&n,&m);
for(int i=; i<=n; ++i) par[i]=i;
while(m--){
scanf("%d%d",&a,&b);
addEdge(a,b); addEdge(b,a);
Union(a,b);
}
memset(d,-,sizeof(d));
int res=;
for(int i=; i<=n; ++i){
if(par[i]==i) res+=max(dfs(i,,),dfs(i,,));
}
printf("Case %d: %d\n",cse,res);
}
return ;
}

最新文章

  1. Node.js:console模块
  2. 如何配置Log4Net使用Oracle数据库记录日志
  3. [转][MVC] 剖析 NopCommerce 的 Theme 机制
  4. 在桌面chrome中调试android设备中的web页面
  5. VirtualBox是什么
  6. 搭建Spring + SpringMVC + Mybatis框架之二(整合Spring和Mybatis)
  7. 指针强转和void*
  8. hadoop2.2编程: 重写comparactor
  9. 配置IIS
  10. windows系统下快捷命令
  11. GameUnity 2.0 文档(一) 事件机制
  12. POI不同版本替换Word模板时的问题
  13. Python基础(文件操作)
  14. Jetty 开发指南:嵌入式开发示例
  15. 源码分析之RequestContextHolder
  16. UDP聊天工具的实现
  17. google 变量命名规则简要记录
  18. jQuery 学习02——效果:隐藏/显示、淡入淡出、滑动、动画、停止动画、Callback、链
  19. 配置文件热加载的go语言实现
  20. 四、Java web 部 分试题

热门文章

  1. java笔记--关于线程死锁
  2. 内存不能为read修复方法:(转自:网上(忘记了))
  3. [HDU5015]233 Matrix
  4. Windows上搭个Nginx集群环境玩玩
  5. Find Leaves of Binary Tree
  6. linux自定义脚本添加到rc.local脚本无法正常运行的问题
  7. Java for LeetCode 057 Insert Interval
  8. HTTP状态码和常用对照表
  9. protostuff简单应用
  10. Java中ArrayList的自我实现