LightOJ1201 A Perfect Murder(树形DP)
2024-09-24 12:17:08
一道经典的树型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 ;
}
最新文章
- Node.js:console模块
- 如何配置Log4Net使用Oracle数据库记录日志
- [转][MVC] 剖析 NopCommerce 的 Theme 机制
- 在桌面chrome中调试android设备中的web页面
- VirtualBox是什么
- 搭建Spring + SpringMVC + Mybatis框架之二(整合Spring和Mybatis)
- 指针强转和void*
- hadoop2.2编程: 重写comparactor
- 配置IIS
- windows系统下快捷命令
- GameUnity 2.0 文档(一) 事件机制
- POI不同版本替换Word模板时的问题
- Python基础(文件操作)
- Jetty 开发指南:嵌入式开发示例
- 源码分析之RequestContextHolder
- UDP聊天工具的实现
- google 变量命名规则简要记录
- jQuery 学习02——效果:隐藏/显示、淡入淡出、滑动、动画、停止动画、Callback、链
- 配置文件热加载的go语言实现
- 四、Java web 部 分试题