当前位置 博文首页 > 文章内容

    洛谷 U140313 暗影已逝

    作者: 栏目:未分类 时间:2020-11-14 15:00:41

    本站于2023年9月4日。收到“大连君*****咨询有限公司”通知
    说我们IIS7站长博客,有一篇博文用了他们的图片。
    要求我们给他们一张图片6000元。要不然法院告我们

    为避免不必要的麻烦,IIS7站长博客,全站内容图片下架、并积极应诉
    博文内容全部不再显示,请需要相关资讯的站长朋友到必应搜索。谢谢!

    另祝:版权碰瓷诈骗团伙,早日弃暗投明。

    相关新闻:借版权之名、行诈骗之实,周某因犯诈骗罪被判处有期徒刑十一年六个月

    叹!百花齐放的时代,渐行渐远!



    洛谷 U140313 暗影已逝

    洛谷传送门

    题目背景

    “光与影轮回不止”

    题目描述

    然而逃跑并不能阻止虫群的袭击。大主教决定吸引更多异虫来到夏古拉斯,在所有星灵撤离后,前往神庙,通过里面的机关来引爆这颗星球,以此重创异虫。

    神庙记载着星灵的历史——光明圣堂武士和黑暗圣堂武士的抗争史。

    机关的形状为一颗无根树。已知每个节点初始没有属性,大主教可用自己的灵能为这些节点添上一种属性(属性仅有两种,黑暗和光明,分别用0和1表示),而每一个叶子节点i都有一个触发属性Ci。Ci定义为从根节点到i上的简单路径上最后一个带有属性的节点的属性(也可以是i本身)。只有每个Ci都符合条件时,机关才可触发。

    虫群已包围神庙,大主教需要在最短的时间内触发机关,于是他找到了你——JDOI滴神。他想知道最少添加几次属性能触发机关。

    输入格式

    第一行两个整数,N,M。分别表示节点的个数和叶子节点的个数。

    第二行M个整数,表示Ci。

    接下来N-1行,每行2个整数x,y。表示x到y有一条边相连。

    输出格式

    一个整数,表示最少操作数。


    题解:

    2020.11.14模拟赛T3 100分场

    积累了宝贵的自己切树形DP的经验。

    代码:

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int maxn=1e6+6;
    int n,m;
    int opt[maxn],cnt[2];
    int tot,head[maxn],nxt[maxn<<1],to[maxn<<1];
    int dp[maxn][2];
    void add(int x,int y)
    {
    	to[++tot]=y;
    	nxt[tot]=head[x];
    	head[x]=tot;
    }
    void dfs(int x,int f)
    {
    	if(x<=m)
    	{
    		if(opt[x])
    			dp[x][0]=1;
    		else
    			dp[x][1]=1;
    		return;
    	}
    	int tmp0=0,tmp1=0;
    	for(int i=head[x];i;i=nxt[i])
    	{
    		int y=to[i];
    		if(y==f)
    			continue;
    		dfs(y,x);
    		tmp0+=dp[y][0];
    		tmp1+=dp[y][1];
    	}
    	dp[x][0]=min(tmp0,tmp1+1);
    	dp[x][1]=min(tmp0+1,tmp1);
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=m;i++)
    		scanf("%d",&opt[i]);
    	for(int i=1;i<n;i++)
    	{
    		int x,y;
    		scanf("%d%d",&x,&y);
    		add(x,y);
    		add(y,x);
    	}
    	dfs(m+1,0);
    	int tmp0=0,tmp1=0;
    	int x=m+1;
    	for(int i=head[x];i;i=nxt[i])
    	{
    		int y=to[i];
    		tmp0+=dp[y][0];
    		tmp1+=dp[y][1];
    	}
    	int ans=min(tmp0,tmp1);
    	printf("%d\n",ans+1);
    	return 0;
    }