[JSOI2015] salesman

题面

题解

考虑树形 DP , 设 \(f[i]\) 为 \(i\) 节点为根的子树最大收益是多少, \(h[i]\) 代表 \(i\) 节点的最优方案是否唯一

转移的话拿个堆记一下子节点中 \(>0\) 的那些, 然后 \(h\) 跟他们的与一下

若是剩下来的有 \(f = 0\) 或是跟你选的是一样的, 这个点 \(i\) 的 \(h\) 就计为 \(0\)

Code

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#define mp(i, j) make_pair(i, j)
const int N = 1e5 +5;
const int INF = 0x3f3f3f3f;
using namespace std;

int n, f[N], tm[N], h[N], head[N], cnte;
struct edge { int to, nxt; } e[N << 1];
priority_queue<pair<int, int> > q; 

template < typename T >
inline T read()
{
    T x = 0, w = 1; char c = getchar();
    while(c < '0' || c > '9') { if(c == '-') w = -1; c = getchar(); }
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * w;
}

inline void adde(int u, int v) { e[++cnte] = (edge) { v, head[u] }, head[u] = cnte; }

void dfs(int u, int fa)
{
    for(int v, i = head[u]; i; i = e[i].nxt)
    {
    v =  e[i].to; if(v == fa) continue;
    dfs(v, u);
    }
    while(!q.empty()) q.pop();
    int tmp = INF;
    for(int v, i = head[u]; i; i = e[i].nxt)
    if((v = e[i].to) != fa) q.push(mp(f[v], v));
    while(!q.empty() && tm[u] && q.top().first > 0)
    {
    f[u] += (tmp = q.top().first), h[u] &= h[q.top().second];
    q.pop(), tm[u]--;
    }
    if(!q.empty() && (q.top().first == tmp || !q.top().first)) h[u] = 0;
}

int main()
{
    n = read <int> ();
    for(int i = 2; i <= n; i++)
    f[i] = read <int> ();
    for(int i = 2; i <= n; i++)
    tm[i] = read <int> () - 1;
    tm[1] = INF, memset(h, 1, sizeof(h));
    for(int u, v, i = 1; i < n; i++)
    u = read <int> (), v = read <int> (), adde(u, v), adde(v, u);
    dfs(1, 0);
    printf("%d\n", f[1]);
    puts(h[1] ? "solution is unique" : "solution is not unique");
    return 0;
}

原文地址:https://www.cnblogs.com/ztlztl/p/12358429.html

时间: 2024-10-12 07:17:42

[JSOI2015] salesman的相关文章

[BZOJ4472] [Jsoi2015]salesman(DFS/排序)

4472: [Jsoi2015]salesman Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 80  Solved: 45[Submit][Status][Discuss] Description 某售货员小T要到若干城镇去推销商品,由于该地区是交通不便的山区,任意两个城镇之间都只有唯一的可能经过其它城镇的路线. 小T 可以准确地估计出在每个城镇停留的净收益.这些净收益可能是负数,即推销商品的利润抵不上花费.由于交通不便,小T经过每个城镇都需要

【题解】 bzoj4472: [Jsoi2015]salesman (动态规划)

bzoj4472,懒得复制,戳我戳我 Solution: 体面意思:从\(1\)号节点出发,每到一个节点就必须停下,获得节点权值(每个节点只会获得一次),每个点有个规定的停留次数,求最大可获得多大权值,并且判断是否只有唯一的路线才能获得这个权值 直接\(dp\)储存子树最大获得权值就行,顺便要记录方案是否唯一,所以我们可以拿一个结构体来记录 \(dp\)权值思路:找出所有子树中前\(vis[i]-1\)大的节点权值(只选大于\(0\)的权值). \(dp\)方案思路: 1.如果有选择的节点是方案

bzoj4472: [Jsoi2015]salesman(树形dp)

Description 某售货员小T要到若干城镇去推销商品,由于该地区是交通不便的山区,任意两个城镇之间都只有唯一的可能经过其它城镇的路线. 小T 可以准确地估计出在每个城镇停留的净收益.这些净收益可能是负数,即推销商品的利润抵不上花费.由于交通不便,小T经过每个城镇都需要停留,在每个城镇的停留次数与在该地的净收益无关,因为很多费用不是计次收取的,而每个城镇对小T的商品需求也是相对固定的,停留一次后就饱和了.每个城镇为了强化治安,对外地人的最多停留次数有严格的规定.请你帮小T 设计一个收益最大的

「JSOI2015」salesman

「JSOI2015」salesman 传送门 显然我们为了使收益最大化就直接从子树中选大的就好了. 到达次数的限制就是限制了可以选的子树的数量,因为每次回溯上来都会减一次到达次数. 多种方案的判断就是看自己选中的子树中和没选的子树中是否存在两个值相等的,这样它们就可以通过互换来达到另一种方案,值得注意的是如果选了一个值为 \(0\) 的子树就肯定可以多一种方案出来,因为这颗子树选或不选都是满足最优的. 这里有个小问题:交到BZOJ上面去它会提示你 sort 没有声明,此时需要 #include

4477: [Jsoi2015]字符串树

4477: [Jsoi2015]字符串树 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 156  Solved: 69[Submit][Status][Discuss] Description 萌萌买了一颗字符串树的种子,春天种下去以后夏天就能长出一棵很大的字 符串树.字符串树很奇特,树枝上都密密麻麻写满了字符串,看上去很复杂的样 子. [问题描述] 字符串树本质上还是一棵树,即N个节点N-1条边的连通无向无环图,节点 从1到N编号.与普通的树不

构造 - HDU 5402 Travelling Salesman Problem

Travelling Salesman Problem Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=5402 Mean: 现有一个n*m的迷宫,每一个格子都有一个非负整数,从迷宫的左上角(1,1)到迷宫的右下角(n,m),并且使得他走过的路径的整数之和最大,问最大和为多少以及他走的路径. analyse: 首先,因为每个格子都是非负整数,而且规定每个格子只能走一次,所以为了使和尽可能大,必定是走的格子数越多越好.这样我们就需

hdu5402 Travelling Salesman Problem(棋盘染色+模拟)

题目: Travelling Salesman Problem Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 906    Accepted Submission(s): 331 Special Judge Problem Description Teacher Mai is in a maze with n rows and m c

HDOJ 5402 Travelling Salesman Problem 模拟

行数或列数为奇数就能够所有走完. 行数和列数都是偶数,能够选择空出一个(x+y)为奇数的点. 假设要空出一个(x+y)为偶数的点,则必须空出其它(x+y)为奇数的点 Travelling Salesman Problem Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 747    Accepted Submission(s): 272

多校9 1007 Travelling Salesman Problem

Travelling Salesman Problem Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 829    Accepted Submission(s): 182Special Judge Problem Description Teacher Mai is in a maze with n rows and m columns