首页 > 其他分享 >[POI2014] TUR-Tourism

[POI2014] TUR-Tourism

时间:2024-09-19 20:51:40浏览次数:1  
标签:TUR POI2014 Tourism 节点 dp define

[POI2014] TUR-Tourism

题意

给出一张图,在这张图中,任意两点间不存在节点数超过 \(10\) 的简单路径。

第 \(i\) 个点被选的代价为 \(C_i\),每个节点要么选,要么与它直接相连的点中至少有一个被选。

求最小代价。

思路

图的生成树上状压动态规划。

由于给出的是一张图,无法直接dp,我们可以在这张图的 dfs 树上dp。

又因为任意两点间不存在节点数超过 \(10\) 的简单路径,

我们可以把每个点到根的路径上点的状态进行压缩。

\(0\):这个点选了。

\(1\):这个点没选也没被覆盖。

\(2\):这个点没选但被覆盖。

每次从子节点回收答案,看子节点选还是不选被覆盖。

每次还需要从父节点继承答案,枚举返祖边。

通过祖先的状态,统计出当前点选和不选时的状态,从父亲的 dp 值继承过来。

实现时用 \(dp_{i,j}\) 表示深度为 \(i\)(而不是点 \(i\)),状态为 \(j\) 的最小值,每次清空节省空间。

代码和注释

#define Get(x, y) ((x) / Pow[y] % 3)
#define Set(x, y, v) (x -= Get(x, y) * Pow[y], x += v * Pow[y])
#define min(x, y) ((x) < (y) ? (x) : (y))
const int N = 1e5 + 5;
/*
0:选了
1:不选且未被覆盖
2:不选且被覆盖
*/
int ver[N << 1], nxt[N << 1], head[N];
int a[N], n, m, tot;
int dep[N], ans, cnt, z[N];
int dp[11][N], Pow[11];
bool vis[N];
void add(int x, int y) {
    ver[++ tot] = y;   
    nxt[tot] = head[x];
    head[x] = tot;
}
void dfs(int x) {
    vis[x] = 1, cnt = 0;
    for (int i = head[x], y; i; i = nxt[i]) {
        y = ver[i];
        if (vis[y]) z[++ cnt] = dep[y]; // 返祖边连向的祖先
    }
    if (dep[x] == 0) { // 根节点
        dp[0][0] = a[x];
        dp[0][1] = 0;
        dp[0][2] = 1e9;
    } else {
        for (int i = 0; i < Pow[dep[x] + 1]; i ++) dp[dep[x]][i] = 1e9; // 赋值
        for (int i = 0; i < Pow[dep[x]]; i ++) { // 枚举父亲状态
            int yes = i, no = i; 
            // yes:当前点选后的状态
            // no:当前点不选后的状态
            Set(no, dep[x], 1); // 初始时就是不选未覆盖 
            for (int j = 1; j <= cnt; j ++) {
                int y = z[j];
                if (Get(i, y) == 0) Set(no, dep[x], 2); // 如果有祖先选了,当前点变为未选被覆盖
                if (Get(i, y) == 1) Set(yes, y, 2); // 如果有祖先不选未覆盖,把它变为未选被覆盖
            }
            dp[dep[x]][no] = min(dp[dep[x]][no], dp[dep[x] - 1][i]); // 没选当前点,直接继承
            dp[dep[x]][yes] = min(dp[dep[x]][yes], dp[dep[x] - 1][i] + a[x]); // 选了当前点,加上权值
        }
    }
    for (int i = head[x], y; i; i = nxt[i]) {
        y = ver[i];
        if (vis[y]) continue;
        dep[y] = dep[x] + 1;
        dfs(y);
        for (int i = 0; i < Pow[dep[y]]; i ++) 
            dp[dep[x]][i] = min(/*选*/dp[dep[y]][i], /*不选被覆盖*/dp[dep[y]][i + 2 * Pow[dep[y]]]); // 从儿子回收答案 
    }
}
int main() {
    memset(dp, 0x3f, sizeof(dp));
    Pow[0] = 1;
    for (int i = 1; i <= 10; i ++)
        Pow[i] = Pow[i - 1] * 3;
    read(n), read(m);
    for (int i = 1; i <= n; i ++) read(a[i]);
    for (int i = 1, u, v; i <= m; i ++) {
        read(u), read(v);
        add(u, v);
        add(v, u);
    }
    for (int i = 1; i <= n; i ++) {
        if (vis[i]) continue;
        dfs(i);
        ans += min(dp[0][0], dp[0][2]);
    }
    print(ans);
    print_final();
    return 0;
}

标签:TUR,POI2014,Tourism,节点,dp,define
From: https://www.cnblogs.com/maniubi/p/18421308

相关文章

  • Professional Linux Kernel Architecture(一)
    基于linux内核2.6.24版本,书籍:ProfessionalLinuxKernelArchitecture英文版(可在https://github.com/welldef/os_books.git下载)1一些概念1.1微内核和单体内核微内核:只有最基本的功能直接在中央内核(微内核)中实现。所有其他功能都委托给各自独立的进程,这些进程通过通信接口与......
  • 易优eyoucms网站php5.4版本,报错:Can't use method return value in write context
    当你在使用PHP5.4版本时遇到“Can'tusemethodreturnvalueinwritecontext”的错误,这通常是因为你在代码中错误地使用了方法返回值。这种错误通常发生在试图将方法返回值直接赋值给变量或用于其他上下文时。解决方案以下是一些常见的原因和解决方法:1.检查代码中的赋......
  • py3.7+win10的cv2.xfeatures2d_SIFT.create()函数不存在问题
    python3.7环境window1064位cv2包问题。问题做图片处理用opencv-python做模板匹配的时候会用个sift模型,就会用到cv2.xfeatures2d_SIFT.create()这个函数,在我正要用它增加自己知识,巴拉巴啦....的时候,咦?!这是个什么鬼哦,没有这个函数呢。百度发现需要什么卸载原版本,换成opencv-......
  • 10. Top-K vs Top-P:生成式模型中的采样策略与 Temperature 的影响
    在之前的文章中我们探讨了BeamSearch和GreedySearch。现在来聊聊model.generate()中常见的三个参数:top-k,top-p和temperature。代码文件下载文章目录Top-K采样详解工作原理数学表述代码示例Top-P采样详解工作原理数学表述代码示例Temperature的作......
  • P3573 [POI2014] RAJ-Rally
    题意给定一个DAG,你需要删掉一个点使得原图的最长路径的长度最短,求出答案和方案。\(n\le5\times10^5,m\le10^6\)分析DAG的一条路径有一个优美的性质:一定是从拓扑序小的点指向拓扑序大的点。考虑按照拓扑序从小到大处理每一个点。假设我们处理到了点\(x\),它的拓扑序是\(i......
  • Nature Genetics | Rajeev K. Varshney综述:解锁植物遗传学的端粒到端粒(T2T)基因组组装
    近期,RajeevK.Varshney团队在Naturegenetics发表综述文章:Unlockingplantgeneticswithtelomere-to-telomeregenomeassemblies。摘要连续基因组序列组装将帮助我们实现作物转化基因组学的全面潜力。最近在测序技术方面的进步,尤其是长读长测序策略,使得构建无间隙的端粒到端粒(T......
  • Nature Comm. | CoPheScan:一种考虑连锁不平衡的全表型组关联分析
    分享一篇最近发表在NC的一篇文章:CoPheScan:phenome-wideassociationstudiesaccountingforlinkagedisequilibrium。文章介绍了一种新的贝叶斯方法CoPheScan(ColocadaptedPhenome-wideScan),用于在考虑连锁不平衡(LD)的情况下进行表型范围关联研究(Phenome-wideassociationstud......
  • 几种提升turtle绘图速度的方法
    问题来源最近老师要求设计程序模拟伽尔顿板。程序设计还是很简单的只需在每次下落时从[0,1]之间产生一个随机整数,若为零则向左反之向右,并用一个变量来记录向右的次数以确定小球的最终出口。但是为了准确性,要投成千上万次,看着小乌龟慢慢爬。。。。光绘制10层柱子都要1分钟。......
  • C++11 线程同步接口std::condition_variable和std::future的简单使用sk
    合集-C++(1)1.C++11线程同步接口std::condition_variable和std::future的简单使用09-17收起std::condition_variable条件变量std::condition_variable有wait和notify接口用于线程间的同步。如下图所示,Thread2阻塞在wait接口,Thread1通过notify接口通知Thread2继续执行。......
  • macOS Ventura 13.7 (22H123) 正式版发布,ISO、IPSW、PKG 下载
    macOSVentura13.7(22H123)正式版发布,ISO、IPSW、PKG下载2024年9月17日凌晨1点,TimCook领导的Apple今天发布了macOS15Sequoia正式版,iPhone镜像、密码应用程序、窗口平铺更新等带来全新体验。Apple还为那些无法升级到Sequoia的用户发布了macOSVentura13.......