本题也是这三天来在下写的几篇树形DP之一,但是不知道为什么洛谷上面老是unknown error,。。。直接去了UVa,说我编译错误。。。我在想是不是头文件的原因,于是被逼无奈,交了一道c89的代码。(结果后来还是CE了)

我真他娘是B了狗了。。。

所以,因为测试数据只过了我们学校的OJ(需要注册才可看题),我会担心有可能代码有问题,欢迎大家杀我祭天指正错误。


题目描述[传送门]

Bob特别喜欢战略游戏,但有时他不能尽快找到最优解,所以他就很伤心。现在他又有一个问题,他必须保卫一个中世纪的城市,这个城市的道路形成了一棵树。他需要在树的节点上放最少的士兵来观察所有的边。你能帮助他么?

例如下图就只需要一个士兵放在1号节点。

输入

输入文件soldier.in中有多组数据,每组数据的第一行N表示点的个数。接下来N行每行格式如下

x:(k) a1 a2 … ak(x为点的编号,k为与其相连的子节点个数,a1, a2, …, ak分别为子节点的编号)

输出

输出文件soldier.out,对于每组数据输出一行一个数,即最少士兵数。

样例输入

4
0:(1) 1
1:(2) 2 3
2:(0)
3:(0)
5
3:(3) 1 4 2
1:(1) 0
2:(0)
0:(0)
4:(0)

样例输出

1
2

提示

0 < N<= 1500, 0
<= x < N


于是这是我写的第三篇关于树形DP的博客。我越来越熟悉这个美妙而不失简洁的算法。。。。然而选课你还是做不来hiahiahia

让我们来简化分析一下:

给定一个无向多叉树,一个节点可以影响和它直接连接的节点,那请问需要至少多少个节点才可以使所有节点都被影响?

动规最重要是定义状态,一个好的状态可以让你的程序写起来更加容易。

在这里我们规定:f[u][0/1]用于表示u号节点放士兵或者不放士兵时的最小士兵数。

那这个时候我们就要想状态转移方程了

要是u节点不放士兵,那必须至少有一条与之相邻的点放了士兵,要是放士兵,则可放可不放,很容易得出f[u][0]=f[u][0]+f[v][1];//v为一个与u相邻的点   f[u][1]=min(f[v][1],f[v][0])

并且在最后不要忘了把f[u][1]给++。

这样状态转移和定义出来了,那么答案就是min(f[root][0],f[root][1]);

下面给出完整代码:

#include<bits/stdc++.h>
namespace Jason{
inline void scan(int &x){
int f=;x=;char s=getchar();
while(s<'' || s>''){if(s=='-') f=-;s=getchar();}
while(s>='' && s<=''){x=x*+s-'';s=getchar();}
x*=f;
}
inline void print(int x){
if(x<){putchar('-');x=-x;}
if(x>)print(x/);char s=x%+'';
putchar(s);
}
struct Edge_B{
int to,dis;
Edge_B* nxt;
Edge_B(int to=-,int dis=-,Edge_B* n=NULL){this->to=to,this->dis=dis,this->nxt=n;}
};
}
using namespace std;
using namespace Jason;
const int maxn=+;
//--------------------
int n,m,cnt=;
struct Edge{
int to,nxt;
}edge[maxn<<];int head[maxn];
int f[maxn][];
//--------------------
void add(int x,int y)
{
edge[++cnt].nxt=head[x];
edge[cnt].to=y;
head[x]=cnt;
} void dp(int u,int fa)
{
for(int i=head[u];i!=-;i=edge[i].nxt)
{
int v=edge[i].to;
if(v==fa) continue;
dp(v,u);
f[u][]+=f[v][];
f[u][]+=min(f[v][],f[v][]);
}
f[u][]++;
} int main()
{
//freopen("in","r",stdin);
int a,b,c;
while(scanf("%d",&n)==)
{
memset(head,-,sizeof(head));
memset(f,,sizeof(f));
for(int i=;i<n;++i)
{
scanf("%d:(%d)",&a,&b);
for(int i=;i<b;++i) scanf("%d",&c),add(a,c),add(c,a);
}
dp(,-);
print(min(f[][],f[][]));putchar('\n');
}
return ;
}

然而我还是不会选课。。。。。

【树形DP】MZOJ_1063_士兵守卫的更多相关文章

  1. BZOJ 2314: 士兵的放置( 树形dp )

    树形dp... dp(x, 0)表示结点x不放士兵, 由父亲控制: dp(x, 1)表示结点x不放士兵, 由儿子控制: dp(x, 2)表示结点x放士兵. ---------------------- ...

  2. 【BZOJ2314】士兵的放置 树形DP

    [BZOJ2314]士兵的放置 Description 八中有N个房间和N-1双向通道,任意两个房间均可到达.现在出了一件极BT的事,就是八中开始闹鬼了.老大决定加强安保,现在如果在某个房间中放一个士 ...

  3. BZOJ 4557 JLOI2016 侦查守卫 树形dp

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4557 题意概述: 给出一棵树,每个点付出代价w[i]可以控制距离和它不超过d的点,现在给 ...

  4. uva 1292 树形dp

    UVA 1292 - Strategic game 守卫城市,城市由n个点和n-1条边组成的树,要求在点上安排士兵,守卫与点相连的边.问最少要安排多少士兵. 典型的树形dp.每一个点有两个状态: dp ...

  5. 树形DP

    切题ing!!!!! HDU  2196 Anniversary party 经典树形DP,以前写的太搓了,终于学会简单写法了.... #include <iostream> #inclu ...

  6. HDU 1011 Starship Troopers 树形DP 有坑点

    本来是一道很水的树形DP题 设dp[i][j]表示,带着j个人去攻打以节点i为根的子树的最大收益 结果wa了一整晚 原因: 坑点1: 即使这个节点里面没有守卫,你如果想获得这个节点的收益,你还是必须派 ...

  7. HDU 1054 Strategic Game (树形dp)

    题目链接 题意: 给一颗树,用最少的点覆盖整棵树. 每一个结点可以防守相邻的一个边,求最少的点防守所有的边. 分析: 1:以当前节点为根节点,在该节点排士兵守护道路的最小消耗.在这种情况下,他的子节点 ...

  8. POJ1463:Strategic game(树形DP)

    Description Bob enjoys playing computer games, especially strategic games, but sometimes he cannot f ...

  9. 树形dp专辑

    hdu 2196 http://acm.hdu.edu.cn/showproblem.php?pid=2196 input 5//5个结点 1 1//表示结点2到结点1有一条权值为1的边 2 1//表 ...

随机推荐

  1. Python学习---range/for/break/continue简单使用

    range的使用:注意,在python3中,交互模式下已经不显示了 for循环的使用 打印50-70 # 第一种方案 for i in range(100): if i <= 70 and i ...

  2. Java学习---IO操作

    基础知识 1.文件操作 Java语言统一将每个文件都视为一个顺序字节流.每个文件或者结束于一个文件结束标志,或者根据系统维护管理数据中所纪录的具体字节数来终止.当一个文件打开时,一个对象就被创建,同时 ...

  3. stderr: xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance

    错误提示: (1). stderr: xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer direc ...

  4. 利用Fiddler2和Proxifier分析你用的中国菜刀是否带有后门

    为了避免自己辛辛苦苦拿下的站点被一些拿来主义者不费吹灰之力就据为己有,下面来教大家如何检测菜刀有没有留后门. 对于有没有后门这个问题,大牛们会说抓包看一下就行了,那如何抓包呢?有很多软件可以,这里使用 ...

  5. canvas小球 时间demo

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  6. iOS 技能分类:

    1.语言与系统: 2.架构与机制: 3.性能:cpu.gpu.io.缓存.内存:性能监测工具: 4.知名开源库:

  7. Java异常总结和Spring事务处理异常机制浅析

    异常的概念和Java异常体系结构 异常是程序运行过程中出现的错误.本文主要讲授的是Java语言的异常处理.Java语言的异常处理框架,是Java语言健壮性的一个重要体现. Thorwable类所有异常 ...

  8. 如何使用Loadrunner12录制WebSocket脚本

    简单说一下,关于Loadrunner12对WebSocket的支持可以参照以下文档: http://community.hpe.com/t5/LoadRunner-and-Performance/As ...

  9. TensorFlow函数(二)tf.get_variable() 和 tf.Variable()

    tf.Variable(<initial - value>,name=<optional - name>) 此函数用于定义图变量.生成一个初始值为initial - value ...

  10. Java50道经典习题-程序20 求前20项之和

    题目:有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13...求出这个数列的前20项之和.分析:请抓住分子与分母的变化规律.三个连续分数之间的规律是:上两个分子之和等于第三个分数的分子 ...