ACM-ICPC(10 / 9)
ACM-ICPC(10.9) 树形DP
树形DP考点很多,状态转移有时会很复杂,但是也有规律可寻,最重要的是抓住父子关系之间的状态转移。
树的最大独立集:尽量选择多的点,使得任何两个结点均不相邻。
状态转移,两种方案:
这样用记忆化的方案来做。
另一种,也是很常见的,也是很重要的——刷表法。
计算出一个 后,去刷新他的父亲,和祖父结点的值。
树的重心:找到一个点,以这个点为重心,最大子树的结点数最小。
这里需要反选,名字瞎起的,也很常见的哦~,
树的直径,也可以用树形DP来做,但是两次DFS更常用。
树形背包。
推荐题目:树形DP很具有思维和编程控制能力,题目较多,认真思考。
BZOJ 3722,1131,4753
Description
Fancy爷宣布XJOI群将要选举下一任群主。候选人有两名,分别是XYW和吉丽。共有n个人(从1~n编号)参加这次投票。他们之间形成了一个树结构,根结点(1号结点)为Fancy。树上的结点有两种身份:专家(叶子结点)或领导(非叶子结点)。每位专家都有自己的选择——支持XYW和吉丽之中的一个;每位领导都有若干个下属(儿子结点),领导的选择决定于下属中人数较多的那一方,下属的数目保证为奇数,从而不会出现平局状况。最后,Fancy的选择即为选举结果。吉丽和XYW知道,目前仍有一些专家处于犹豫未决的状态,只要前去游说,就可获得他的支持。但是由于精力不够,每人每天只能选择游说1名专家;XYW起床更早,他比吉丽先进行游说。这样两人交替进行,直到每位专家都有了确定的选择。请问XYW是否有策略保证自己赢得选举胜利?
Input
第一行一个整数n(2<=n<=1000),表示人数。接下来有n行。第i行中,第一个数为ci。如果c[i]<=0,则i是专家,-2表示其支持XYW,-1表示支持吉丽,0表示仍在犹豫;如果c[i]>0,则c[i]为奇数,表示i是领导,其后c[i]个整数为i的下属。(数据保证为树结构,即除了根节点1以外每个结点有且仅有一个上级)
Output
若XYW无法保证胜利,仅输出一行NIE。否则,输出第一行包含TAK和一个非负整数d;输出第二行包含d个整数,按升序排列,表示XYW在必胜策略下,第一天可以选择游说的专家的编号。(如果不存在犹豫不决的专家,且XYW获得胜利的情况下,则d=0,第二行为空行)
Sample Input
43 2 3 4-20-1
Sample Output
TAK 13
HINT
乍一眼看去,很是复杂,树形博弈SG函数,挺麻烦的,但是数据量很小,考虑枚举O(n^2)。
枚举每一个犹豫的人,看是否必胜,统计贡献值即可~
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1005;
struct Edge {
int to,next;
}e[maxn*2];
int tot;
int n;
int c[maxn];
int head[maxn];
void add(int u,int v) {
e[++tot].to = v;
e[tot].next = head[u];
head[u] = tot;
}
int col[maxn];
int dfs(int u) {
if(c[u]<=0) return col[u];
int sum = 0;
for(int i = head[u]; i ; i = e[i].next) {
int v = e[i].to;
sum+=dfs(v);
}
if(sum<0) return -1;
if(sum>0) return 1;
return 0;
}
int main()
{
freopen("in.txt","r",stdin);
scanf("%d",&n);
for(int i = 1; i <= n; i++) {
scanf("%d",&c[i]);
for(int j = 1; j <= c[i]; j++) {
int v;
scanf("%d",&v);
add(i,v);
}
if(c[i]==-2)
col[i] = 1;
if(c[i]==-1)
col[i] = -1;
if(c[i]==0)
col[i] = 0;
if(c[i]>0)
col[i] = 0x3f3f3f3f;
}
if(dfs(1)==-1) {
puts("NIE");
return 0;
}
vector<int> ans;
for(int i = 1; i <= n; i++) {
if(col[i]==0) {
col[i] = 1;
if(dfs(1)==1) {
ans.push_back(i);
}
col[i] = 0;
}
}
printf("TAK %d\n",ans.size());
if(ans.size()>0)
printf("%d",ans[0]);
for(int i = 1; i < (int)ans.size(); i++)
printf(" %d",ans[i]);
puts("");
return 0;
}
1131
Description
给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大
Input
给出一个数字N,代表有N个点.N<=1000000 下面N-1条边.
Output
输出你所找到的点,如果具有多个解,请输出编号最小的那个.
Sample Input
81 45 64 56 76 82 43 4
Sample Output
7
抓住父子关系,大部分的树形DP都是自底向上做的,这题例外很少见哦~
: 深度之和。
作为儿子结点,可以很容易的转移: 这里就用到反选了哦。
这个DP前提是 算对的情况。因此要自顶向上转移。
树形DP,有很多OJ用vector建树会超时,还是习惯用head的向前星形式的哦。
#include <bits/stdc++.h> using namespace std; const int maxn = 1e6+5;
typedef long long ll; vector<int> g[maxn];
ll sz[maxn];
int dep[maxn];
ll f[maxn];
int n; /*
void dfs1(int u,int fa,int d) {
sz[u] = 1;
dep[u] = d;
f[u] = dep[u];
for(int i = 0; i <(int)g[u].size(); i++) {
int v = g[u][i];
if(v==fa) continue;
dfs1(v,u,d+1);
sz[u] +=sz[v];
f[u] +=f[v];
}
} ll minn;
int ret;
void dfs2(int u,int fa) {
for(int i = 0; i < (int)g[u].size(); i++) {
int v = g[u][i];
if(v==fa) continue;
f[v] = f[u] - sz[v] + n - sz[v];
dfs2(v,u);
}
}
*/ struct Edge {
int to,next;
}e[maxn*2]; int cnt;
int head[maxn];
void add(int u,int v) {
e[++cnt].to = v;
e[cnt].next = head[u];
head[u] = cnt;
} void dfs1(int u,int fa,int d) {
sz[u] = 1;
dep[u] = d;
f[u] = dep[u];
for(int i = head[u]; i; i=e[i].next) {
int v = e[i].to;
if(v==fa) continue;
dfs1(v,u,d+1);
sz[u] +=sz[v];
f[u] +=f[v];
}
} ll minn;
int ret; void dfs2(int u,int fa) {
for(int i = head[u]; i; i=e[i].next) {
int v = e[i].to;
if(v==fa) continue;
f[v] = f[u] - sz[v] + n - sz[v];
dfs2(v,u);
}
} int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
} int main()
{
//scanf("%d",&n);
n = read();
int u,v;
for(int i = 1; i < n; i++) {
u = read();
v = read();
add(u,v);
add(v,u);
} dfs1(1,0,0);
dfs2(1,0);
minn = -1;
for(int i = 1; i <= n; i++) {
if(minn<f[i])
{
minn = f[i];
ret = i;
}
}
printf("%d\n",ret);
return 0;
}
bzoj 4753
需要用到01分数规划。
先做两个01分数规划的入门题吧~
ACM-ICPC(10 / 9)的更多相关文章
- 程序设计入门——C语言 第5周编程练习 1高精度小数(10分)
1 高精度小数(10分) 题目内容: 由于计算机内部表达方式的限制,浮点运算都有精度问题,为了得到高精度的计算结果,就需要自己设计实现方法. (0,1)之间的任何浮点数都可以表达为两个正整数的商,为了 ...
- PTA练习题之7-1 矩阵转置(10 分)
7-1 矩阵转置(10 分) 将一个3×3矩阵转置(即行和列互换). 输入格式: 在一行中输入9个小于100的整数,其间各以一个空格间隔. 输出格式: 输出3行3列的二维数组,每个数据输出占4列. 输 ...
- PTA练习题之6.1统计字符串中大小写字母的个数(10 分)
统计字符串中大小写字母的个数(10 分) 分别统计字符串中大写字母和小写字母的个数. 函数接口定义: void fun ( char *s, int *a, int *b ); 其中s.a.b 都是用 ...
- PTA 最大子列和问题(10 分)
最大子列和问题(10 分) 给定K个整数组成的序列{ N1, N2, ..., NK },“连续子列”被定义为{ Ni, Ni+1, ..., Nj },其中 1≤ ...
- test 5.1 高精度小数(10分)
请写一个程序,输入一个分数,计算出它的小数形式.无论是否可以除尽,输出最多小数点后200位. 题目内容 由于计算机内部表达方式的限制,浮点运算都有精度问题,为了得到高精度的计算结果,就需要自己设计实现 ...
- 环状序列(Circular Sequence, ACM/ICPC Seoul 2004, UVa1584)
长度为n的环状串有n种表示法,分别为从某 个位置开始顺时针得到.例如,图3-4的环状串 有10种表示: CGAGTCAGCT,GAGTCAGCTC,AGTCAGCTCG等. 在这些表示法中,字典序最小 ...
- SQL Server安全(10/11):行级别安全(Row-Level Security)
在保密你的服务器和数据,防备当前复杂的攻击,SQL Server有你需要的一切.但在你能有效使用这些安全功能前,你需要理解你面对的威胁和一些基本的安全概念.这篇文章提供了基础,因此你可以对SQL Se ...
- Docker系列教程01-Centos7安装新版Docker教程(10步)
最近一直忙于开发,没有时间好好总结一下docker的知识.其实现在docker的教程已经很多很多了,但是很多系统的教程都是基于Ubuntu系统,因为官方推荐使用Ubuntu系统啊,原因在于Ubuntu ...
- 欢迎来怼——第14次Scrum会议(10/26)
一.小组信息 队名:欢迎来怼小组成员队长:田继平成员:李圆圆,葛美义,王伟东,姜珊,邵朔,冉华 小组照片 二.开会信息 时间:2017/10/26 17:00~17:13(总计13min).地点:计 ...
随机推荐
- 转 Oracle]如何在Oracle中设置Event
https://www.cnblogs.com/gaojian/p/7619960.html 为了调查Oracle 的故障,可以通过设置event ,来了解详细的状况.方法如下: ■ 如果使用 SPF ...
- Reading a IMU Without Kalman: The Complementary Filter
目标是将惯性测量元件(IMU)之中陀螺仪.加速计的数据结合使用.Kalman filter太复杂,在微机上倾向用一种更简单的方法:Complementary filter 姿态估计(获得3个角度,俯仰 ...
- oracle12C--DG 状态集
一,物理备库 01,状态查询与状态详解 select switchover_status from v$database 02,状态转换到备用数据库 alter database commit to ...
- rsync 问题总结
Rsync服务常见问题汇总讲解:==================================1. rsync服务端开启的iptables防火墙 [客户端的错误] No route to ...
- GreenPlum 大数据平台--外部表(三)
一,外部表介绍 Greenplum 在数据加载上有一个明显的优势,就是支持数据的并发加载,gpfdisk是并发加载的工具,数据库中对应的就是外部表 所谓外部表,就是在数据库中只有表定义.没有数据,数据 ...
- AUTO Uninstaller【教程】AUTODESK系列软件MAYA,3DSMAX,CAD,INVENTOR,REVIT修复卸载工具 Windows x64位
小伙伴是不是遇到 MAYA/CAD/3DSMAX/INVENTOR/REVIT 安装失败或者安装不了的问题了呢?AUTODESK系列软件着实令人头疼,MAYA/CAD/3DSMAX/INVENTOR/ ...
- java语言编程使用正则表达式来实现提取(美团 3-5年经验 15-30k 北京 hadoop高级工程)中的3-5和15-30
不多说,直接上干货! 如有这样的一条数据进来: 美团 3-5年经验 15-30k 北京 hadoop高级工程 //正则表达式提取工资值,因为15-30k后面有k,3-5年经验,不干净 public ...
- 搭建基于Ubuntu的开发环境
基于ubuntu 16.04 LTS经验 分区方案 内存:4G,硬盘:500G 分区 大小 说明 备注 / 20G 说明 swap 6G 说明 /tmp 15G 临时文件 /var 40G 可变数据目 ...
- C#的params参数遇到null
params参数支持数组作为参数传入,但并不支持List 定义一个使用params的参数 private static void UseParam(params int[] args) { if (a ...
- 使用params
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...