每次求出最长链更新答案后要将最长链上的边权改为-1

写的贼长 还可以优化...

 /*Huyyt*/
#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define pb push_back
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const int MAXN = 1e5 + , MAXM = 2e5 + ;
int to[MAXM << ], nxt[MAXM << ], Head[MAXN], ed = ;
int value[MAXM << ];
inline void addedge(int u, int v, int val)
{
to[++ed] = v;
nxt[ed] = Head[u];
value[ed] = val;
Head[u] = ed;
}
int d[MAXN];
void dfs(int x, int pre)
{
for (int v, i = Head[x]; i; i = nxt[i])
{
v = to[i];
if (v == pre)
{
continue;
}
d[v] = d[x] + value[i];
dfs(v, x);
}
}
void change(int x)
{
for (int v, i = Head[x]; i; i = nxt[i])
{
v = to[i];
if (d[v] == d[x] - )
{
value[i] = value[i ^ ] = -;
change(v);
}
}
}
int s, t, dmx = -;
int ans2 = , vis[MAXN], dpd[MAXN];
void dp(int x)
{
vis[x] = ;
for (int v, i = Head[x]; i; i = nxt[i])
{
v = to[i];
if (vis[v])
{
continue;
}
dp(v);
ans2 = max(ans2, dpd[x] + dpd[v] + value[i]);
dpd[x] = max(dpd[x], dpd[v] + value[i]);
}
}
int main()
{
int anser;
int n, k;
int u, v;
scanf("%d %d", &n, &k);
for (int i = ; i < n; i++)
{
scanf("%d %d", &u, &v);
addedge(u, v, ), addedge(v, u, );
}
anser = * (n - );
d[] = ;
dfs(, );
for (int i = ; i <= n; i++)
{
if (d[i] > dmx)
{
dmx = d[i];
s = i;
}
}
d[s] = ;
dfs(s, );
dmx = -;
for (int i = ; i <= n; i++)
{
if (d[i] > dmx)
{
dmx = d[i];
t = i;
}
}
anser -= d[t] - ;
if (k == )
{
printf("%d\n", anser);
return ;
}
change(t);
dp();
anser -= ans2 - ;
printf("%d\n", anser);
return ;
}

//BZOJ1912

求树直径dp

 void dp(int x)
{
vis[x] = ;
for (int v, i = Head[x]; i; i = nxt[i])
{
v = to[i];
if (vis[v])
{
continue;
}
dp(v);
ans2 = max(ans2, dpd[x] + dpd[v] + value[i]);
dpd[x] = max(dpd[x], dpd[v] + value[i]);
}
}

其实这个dp的作用是先把无根树转化为有根树 再求每个点子树中的最长链和次长链(如果有次长链的话)

则树的直径有两种情况

1.是一个节点的最长链

2.是一个节点的次长链+最长链

我们首先记录直径取最长是在哪个节点 然后在每个节点我们都要记录 次长链是那条边拓展出去和最长链是那条边拓展出去

因为一个节点的最长链和次长链必定是一个边加下一个节点的最长链

这样就可以一个dfs搞定

 /*Huyyt*/
#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define pb push_back
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const int MAXN = 1e5 + , MAXM = 1e5 + ;
int to[MAXM << ], nxt[MAXM << ], Head[MAXN], ed = ;
int value[MAXM << ];
inline void addedge(int u, int v, int val)
{
to[++ed] = v;
nxt[ed] = Head[u];
value[ed] = val;
Head[u] = ed;
}
int mxlen[MAXN], mxlen2[MAXN];
int ansdis = ; //直径大小
int s, t;
int dfs(int x, int pre)
{
int mx1 = , mx2 = ; //当前节点的最长链和次长链长度
int now;
for (int v, i = Head[x]; i; i = nxt[i])
{
v = to[i];
if (v == pre)
{
continue;
}
now = dfs(v, x) + value[i];
if (now > mx1)
{
mx2 = mx1;
mxlen2[x] = mxlen[x];
mx1 = now;
mxlen[x] = i; //更新最长链 原最长链变为次长链
}
else if (now > mx2)
{
mx2 = now;
mxlen2[x] = i; //更新次长链
}
}
if (mx1 + mx2 > ansdis)
{
ansdis = mx1 + mx2;
s = x;
}
return mx1;//返回每个节点的最长链大小
}
int main()
{
int anser;
int n, k;
int u, v;
scanf("%d %d", &n, &k);
for (int i = ; i < n; i++)
{
scanf("%d %d", &u, &v);
addedge(u, v, ), addedge(v, u, );
}
anser = * (n - );
dfs(, );
anser -= ansdis - ;
if (k == )
{
printf("%d\n", anser);
return ;
}
ansdis = ;
for (int i = mxlen[s]; i; i = mxlen[to[i]]) //最长链上的边重置为-1
{
value[i] = value[i ^ ] = -;
}
for (int i = mxlen2[s]; i; i = mxlen[to[i]]) //次长链上的边重置为-1
{
value[i] = value[i ^ ] = -;
}
dfs(, );
anser -= ansdis - ;
printf("%d\n", anser);
return ;
}

BZOJ1912 最长链树形DP的更多相关文章

  1. $Loj10155$ 数字转换(求树的最长链) 树形$DP$

    loj Description 如果一个数x的/约数和/y(不包括他本身)比他本身小,那么x可以变成y,y 也可以变成x.限定所有数字变换在不超过n的正整数范围内进行,求不断进行数字变换且不出现重复数 ...

  2. 中南大学oj 1317 Find the max Link 边权可以为负的树上最长路 树形dp 不能两遍dfs

    http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1317经典问题:树上最长路,边权可以为负值的,树形dp,不能用两边dfs.反例:5 41 2 22 ...

  3. 【CF1009F】 Dominant Indices (长链剖分+DP)

    题目链接 \(O(n^2)\)的\(DP\)很容易想,\(f[u][i]\)表示在\(u\)的子树中距离\(u\)为\(i\)的点的个数,则\(f[u][i]=\sum f[v][i-1]\) 长链剖 ...

  4. hdu 6501 transaction transaction transaction 最长路/树形DP/网络流

    最长路: 设置一个虚拟起点和虚拟终点,每个点与起点间一条负边,值为这个点书的价值的相反数(代表买书花钱),每个点与终点连一条正边,值为这个点的书的价格(代表卖书赚钱). 然后按照图中给的边建无向边,权 ...

  5. 2019.01.08 bzoj4543: [POI2014]Hotel加强版(长链剖分+dp)

    传送门 代码: 长链剖分好题. 题意:给你一棵树,问树上选三个互不相同的节点,使得这个三个点两两之间距离相等的方案数. 思路: 先考虑dpdpdp. fi,jf_{i,j}fi,j​表示iii子树中离 ...

  6. 牛客网 桂林电子科技大学第三届ACM程序设计竞赛 G.路径-带条件的树的直径变形-边权最大,边数偶数的树上的最长路径-树形dp

    链接:https://ac.nowcoder.com/acm/contest/558/G 来源:牛客网 路径 小猫在研究树. 小猫在研究路径. 给定一棵N个点的树,每条边有边权,请你求出最长的一条路径 ...

  7. HihoCoder1050 树中的最长路 树形DP第三题(找不到对象)

    题意:求出的树中距离最远的两个结点之间相隔的距离. 水题一道,以前只会用路的直径来解. 代码如下: #include<cstdio> #include<cstdlib> #in ...

  8. 【BZOJ4543】[POI2014]Hotel加强版 长链剖分+DP

    [BZOJ4543][POI2014]Hotel加强版 Description 同OJ3522数据范围:n<=100000 Sample Input 7 1 2 5 7 2 5 2 3 5 6 ...

  9. P7581-「RdOI R2」路径权值【长链剖分,dp】

    正题 题目链接:https://www.luogu.com.cn/problem/P7581 题目大意 给出\(n\)个点的有边权有根树,\(m\)次询问一个节点\(x\)的所有\(k\)级儿子两两之 ...

随机推荐

  1. UnitTest之Xunit

    Unit Test 1.建立单元测试 新建一个类库项目,在Nuget中搜索xunit,选择 xUnit.net 和 xunit.runner.visualstudio 插件包安装. xunit.run ...

  2. Leetcode之动态规划(DP)专题-53. 最大子序和(Maximum Subarray)

    Leetcode之动态规划(DP)专题-53. 最大子序和(Maximum Subarray) 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和. ...

  3. 包含时间的Json序列化

    public static string ObjectToJson<T>(T t) { using (MemoryStream ms = new MemoryStream()) { Dat ...

  4. Web Service简介与开发实例

    简介 1.1.Web Service基本概念 Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的 ...

  5. JAVA师徒架构班 - 带徒模式

    (转: http://www.jeecg.org/forum.php?mod=viewthread&tid=2291&extra=page%3D1&page=1) 一个程序员技 ...

  6. 菜鸟系列Fabric——Fabric 基本概念(1)

    Fabric 基本概念 1.区块链介绍 区块链之所以引来关注是因为比特币开源项目,尤其是比特币价值的飙升,让大家开始关注数字货币以及相关技术.那么区块链究竟是什么? 1.1 区块链定义 狭义上,区块链 ...

  7. 2019年8月22日 星期四(怎样成为PHP大牛)

    1.服务器方面,各种PHP部署方案烂熟,Lvs,keepalived,nginx,apache,docker,换句话说其战力值相当于一个高级运维,迅速定位并排除PHP运行中的各种问题. 2.数据库方面 ...

  8. Postgresql 大小版本升级

    文章结构如下: Postgresql是一个非常活跃的社区开源项目,更新速度很快,每一次版本的更新都会积极的修复旧版本的BUG,性能上也会有不同幅度的提升.10之前的版本由三部分组成,10开始只有两部分 ...

  9. opencv中的高维矩阵Mat

    本示例程序主要是通过实例演示高维Mat的寻址方式. //3,4分别表示行数.列数,所以3*4是一个页面的元素数,2表示有2个3*4 ,b=,c=; int size[]={a,b,c}; float* ...

  10. springboot(二十二)-sharding-jdbc-读写分离

    前面我们使用sharding-jdbc配置了分库分表.sharding-jdbc还有个用法,就是实现读写分离. 什么时候需要或者可以使用读写分离? 当我们的项目所使用的数据库查询的访问量,访问频率,及 ...