多彩的树 -----题解(状压dp + 容斥原理)

news2024/11/27 16:48:58

目录

多彩的树

题目描述 

输入描述:

输出描述:

输入

输出

思路解析:

代码实现:


多彩的树

时间限制:C/C++ 5秒,其他语言10秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述 

有一棵树包含 N 个节点,节点编号从 1 到 N。节点总共有 K 种颜色,颜色编号从 1 到 K。第 i 个节点的颜色为 Ai。
Fi 表示恰好包含 i 种颜色的路径数量。请计算:

输入描述:

第一行输入两个正整数 N 和 K,N 表示节点个数,K 表示颜色种类数量。
第二行输入 N 个正整数,A1, A2, A3, ... ..., AN,Ai 表示第 i 个节点的颜色。

接下来 N - 1 行,第 i 行输入两个正整数 Ui 和 Vi,表示节点 Ui 和节点 Vi 之间存在一条无向边,数据保证这 N-1 条边连通了 N 个节点。

1 ≤ N ≤ 50000.
1 ≤ K ≤ 10.
1 ≤ Ai ≤ K.

输出描述:

输出一个整数表示答案。

示例1

输入

复制

5 3
1 2 1 2 3
4 2
1 3
2 1
2 5

输出

复制

4600065

思路解析:

状压dp + 容斥原理

dp[i] 表示在状态i下·的路径树, 状态i用二进制表示,i==10010,表示使用了颜色2和5,因为这里考虑已经使用了那些颜色比考虑现在的使用的颜色数量更任意统计,并且状态更加明确方便状态转移。

cnt 表示在状态10010下,在某个位置有多少个颜色2和5的节点相邻。cnt + (cnt) * (cnt - 1) / 2则表示当前状态下可能的路径方案总数。

dp[i] = (dp[i] + cnt + (cnt) * (cnt - 1) / 2) % mod;

因为可能有可能是 2 2 2 2 5 5 5.这样简单的cnt + (cnt) * (cnt - 1) / 2计算可能会导致计算有误,所以要排除非法答案。即状态为 00010和状态10000的情况。

if ((j & i) == j){
// System.out.println(i + " " + j);
dp[i] = (dp[i] - dp[j] + mod) % mod;
}

代码实现:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.Arrays;
import java.util.Scanner;
import java.util.Vector;

/**
 * @ProjectName: study3
 * @FileName: Ex35
 * @author:HWJ
 * @Data: 2023/11/10 11:45
 */
public class Ex35 {
    static int mod = 1000000007;
    static long[] dp;
    static long cnt;
    static Vector<Vector<Integer>> g;
    static int[] vis;
    static int[] col;

    public static void main(String[] args) throws IOException {
        Scanner input = new Scanner(System.in);
        StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        in.nextToken();
        int n = (int) in.nval;
        in.nextToken();
        int m = (int) in.nval;
        int[] pow = new int[m + 1];
        for (int i = 0; i < m; i++) {
            pow[i + 1] = (int) quick(i + 1);
        }
        dp = new long[1 << m]; // 用颜色做状态转移。
        vis = new int[n + 1];
        g = new Vector<>();
        col = new int[n + 1];
        for (int i = 0; i < n; i++) {
            in.nextToken();
            col[i + 1] = (int) in.nval;
        }
        for (int i = 0; i < n + 1; i++) {
            g.add(new Vector<>());
        }
        for (int i = 0; i < n - 1; i++) {
            in.nextToken();
            int x = (int) in.nval;
            in.nextToken();
            int y = (int) in.nval;
            g.get(x).add(y);
            g.get(y).add(x);
        }
        for (int i = 1; i < 1 << m; i++) {
            Arrays.fill(vis, 0);
            for (int j = 1; j <= n; j++) {
                cnt = 0;
                if ((i & (1 << (col[j] - 1))) == 0 || vis[j] == 1) continue;
                dfs(j, 0, i);
                dp[i] = (dp[i] + cnt + (cnt) * (cnt - 1) / 2) % mod;
//                System.out.println(i + " " + (j - 1) + " " + cnt);
            }
            for (int j = i - 1; j > 0; j--) {
                if ((j & i) == j){
//                    System.out.println(i + " " + j);
                    dp[i] = (dp[i] - dp[j] + mod) % mod;
                }

            }
        }
        long ans = 0;
        for (int i = 1; i <1 << m; i++) {
            int t = 0;
            int k = i;
            System.out.println(dp[i]);
            while (k > 0){
                if ((k & 1) != 0) t++;
                k >>= 1;
            }
            ans = (ans + (long) pow[t] * dp[i]) % mod;
        }
        System.out.println(ans);
    }

    public static void dfs(int x, int fa, int st){
        cnt++;
        vis[x] = 1;
        for (int i = 0; i < g.get(x).size(); i++) {
            int y = g.get(x).get(i);
            if (y == fa || (st & (1 << (col[y] - 1))) == 0 || vis[y] == 1) continue;
            dfs(y, x, st);
        }
    }

    public static long quick(int p) {
        long ans = 1;
        long x = 131;
        for (; p > 0; p >>= 1, x = (x * x) % mod) {
            if ((p & 1) == 1) ans = (ans * x) % mod;
        }
        return ans;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1192769.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java springBoot 一个demo搞定大文件上传 分片上传 断点续传 秒传

java springBoot js 大文件上传分片上传 断点续传 秒传 文件上传在项目开发中再常见不过了&#xff0c;大多项目都会涉及到图片、音频、视频、文件的上传&#xff0c;通常简单的一个Form表单就可以上传小文件了&#xff0c;但是遇到大文件时比如1GB以上&#xff0c;或者用户网…

WebSocket魔法师:打造实时应用的无限可能

1、背景 在开发一些前端页面的时候&#xff0c;总是能接收到这样的需求&#xff1a;如何保持页面并实现自动更新数据呢&#xff1f;以往的常规做法&#xff0c;是前端使用定时轮询后端接口&#xff0c;获取响应后重新渲染前端页面&#xff0c;这种做法虽然能达到类似的效果&…

Mac电脑Visio文件编辑查看软件推荐Visio Viewer for Mac

mac版Visio Viewer功能特色 在Mac OS X上查看Visio绘图和图表 在Mac OS X上轻松查看MS Visio文件 在Mac上快速方便地打开并阅读Visio文件&#xff08;.vsd&#xff0c;.vsdx&#xff09;。 支持通过放大&#xff0c;缩小&#xff0c;旋转&#xff0c;文本选择和复制&#xff0…

Langchain知识点(上)

输出格式 Pydantic (JSON) 解析器 # 创建模型实例 from langchain import OpenAI model OpenAI(model_nametext-davinci-003)# ------Part 2 # 创建一个空的DataFrame用于存储结果 import pandas as pd df pd.DataFrame(columns["flower_type", "price"…

Python万圣节礼物

文章目录 系列文章前言小海龟快速入门万圣节蝙蝠万圣节南瓜头万圣节礼物尾声 系列文章 序号文章目录直达链接1浪漫520表白代码https://want595.blog.csdn.net/article/details/1306668812满屏表白代码https://want595.blog.csdn.net/article/details/1297945183跳动的爱心http…

MySQL窗口函数——让查询变得更简单

文章目录 一、窗口函数概述1、什么是窗口函数2、窗口函数有哪些&#xff08;1&#xff09;聚合函数&#xff08;聚合函数不是本文讨论的重点&#xff09;&#xff08;2&#xff09;专用窗口函数 3、基本语法4、测试数据准备 二、窗口函数使用1、初识窗口函数&#xff1a;使用聚…

微头条项目实战:新增RequestHeader注解

1、RequestHeader package com.csdn.mymvc.annotation; import java.lang.annotation.*; Target(ElementType.PARAMETER) Retention(RetentionPolicy.RUNTIME) Inherited public interface RequestHeader { }2、DispatcherServlet package com.csdn.mymvc.core; import com.csd…

ssm+vue的项目管理平台(有报告)。Javaee项目,ssm vue前后端分离项目。

演示视频&#xff1a; ssmvue的项目管理平台&#xff08;有报告&#xff09;。Javaee项目&#xff0c;ssm vue前后端分离项目。 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 项目介绍…

list部分接口模拟实现(c++)

List list简介list基本框架list构造函数list_node结构体的默认构造list类的默认构造 push_back()iteartor迭代器迭代器里面的其他接口const迭代器通过模板参数实现复用operator->() insert()erase()clear()析构函数迭代器区间构造拷贝构造operator() list简介 - list可以在…

用友NC Cloud accept.jsp接口任意文件上传漏洞复现 [附POC]

文章目录 用友NC Cloud accept.jsp接口任意文件上传漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06 修复建议 用友NC Cloud accept.jsp接口任意文件上传漏洞复现 [附POC] 0x01 前言 免责声明&#xff1a…

RVS—面向目标硬件的软件性能测试工具

产品概述 Rapita Verification Suite&#xff08;简称&#xff1a;RVS&#xff09;&#xff0c;为美国Danlaw公司提供的一款嵌入式系统在板测试套件&#xff0c;主要应用于汽车领域。其产品符合ISO-26262、DO178B/C、IEC-61508等行业标准&#xff0c;兼容Vxworks、Linux、SYSBI…

FTP链接如何直接打开不输密码

发布版本时&#xff0c;通过分享链接给负责生产的同事遇到如下较为麻烦的小问题 打开公司FTP链接&#xff1a; ftp://192.168.70.46/Rtos_5/FF615/3602/product/ 会跳出如下弹窗提示输入登录密码&#xff0c;这样对方还需要手动输入密码才能把包下下来&#xff1a; 通过直接给…

【ATTCK】MITRE ATTCK 设计与哲学

MITRE ATT&CK™:设计与哲学 来源&#xff1a;MITRE ATT&CK™: Design and Philosophy 摘要 MITRE ATT&CK知识库描述了网络对手的行为&#xff0c;并为攻击和防御提供了一个通用的分类。它已成为跨许多网络安全领域的一个有用工具&#xff0c;用于传递威胁情报&…

【干货】132道最新K8S面试题汇总~

k8s全称kubernetes&#xff0c;这个名字大家应该都不陌生&#xff0c;k8s是为容器服务而生的一个可移植容器的编排管理工具&#xff0c;越来越多的公司正在拥抱k8s&#xff0c;并且当前k8s已经主导了云业务流程&#xff0c;推动了微服务架构等热门技术的普及和落地&#xff0c;…

日常交流没有障碍,听力就一定正常吗?

你卖灯笼啊&#xff1f; 对啊对啊&#xff0c;我耳朵聋&#xff01; 你这灯笼多少钱呀&#xff1f; 我耳朵聋了好几年啦&#xff01; 这是个笑话 当然也可以从中看出 听力障碍对一个人日常生活的影响 日常交流没障碍 就是听力正常了吗&#xff1f; 首先我们要了解&#xf…

6大顶级团队计划目标管理软件盘点,全行业适用!

在快节奏的现代工作环境中&#xff0c;高效的团队计划和执行是团队取得成功的关键。然而&#xff0c;随着团队规模不断增大、工作任务不断增加&#xff0c;如何提高团队计划与效率成为了一个挑战。幸运的是&#xff0c;有许多先进的软件工具可以帮助团队更好地组织、协调和追踪…

关于c++中数据sqrt() 精度问题

情景介绍 今天在做一个算法题目的时候&#xff0c;发现&#xff0c;当使用sqrt()方法进行开方的时候&#xff0c;一直存在提交不通过的情况。 问题分析 对数据不断分析后&#xff0c;发现对35进行开方后&#xff0c;仍然满足条件&#xff0c;这就存在问题。 sqrt(35) 5.9160…

SOLIDWORKS软件提供了哪些特征造型方法?硕迪科技

SOLIDWORKS作为一款三维设计软件&#xff0c;为用户提供了多种特征造型方法&#xff0c;以下是其中几种常用的&#xff1a; 实体建模特征&#xff1a;SOLIDWORKS使用实体建模技术来创建和编辑三维几何体。通过使用基本几何体&#xff08;如立方体、圆柱体、圆锥体等&#xff09…

【广州华锐互动】楼宇智能化VR虚拟教学系统

在如今的技术时代&#xff0c;教育行业正在逐步引入各种创新方法以提升教学质量。VR公司广州华锐互动开发的楼宇智能化VR虚拟教学系统就是其中的一种&#xff0c;它利用虚拟现实(VR)技术&#xff0c;为学生提供一种全新的、沉浸式的学习体验。 楼宇智能化VR虚拟教学系统涵盖综合…

“我为家乡代言”第三届iEnglish英语风采秀即将启动

近期,第二届iEnglish英语风采秀活动圆满落幕,超2万名来自全国各地的青少年儿童通过此平台展示了他们的英语才华和自信。如今,第三届iEnglish英语风采秀即将于12月底正式启动。 据悉,iEnglish英语风采秀旨在为全国青少年儿童提供一个专属于自己的英语展示舞台,通过英文演讲的模…