每次求出最长链更新答案后要将最长链上的边权改为-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. iOS检测用户截屏, 并获取所截图片

    // // ViewController.m // CheckScreenshotDemo // // Created by 思 彭 on 2017/4/25. // Copyright © 2017 ...

  2. ios8唤不起APP的问题

    https://stackoverflow.com/questions/27526966/ios-8-window-location-href-doesnt-work-with-url-scheme ...

  3. django使用session来保存用户登录状态

    先建好登录用的model,其次理解使用cookie和session的原理,一个在本机保存,一个在服务器保存 使用session好处,可以设置登录过期的时间, 编写views中login的函数 def ...

  4. Pytorch修改ResNet模型全连接层进行直接训练

    之前在用预训练的ResNet的模型进行迁移训练时,是固定除最后一层的前面层权重,然后把全连接层输出改为自己需要的数目,进行最后一层的训练,那么现在假如想要只是把 最后一层的输出改一下,不需要加载前面层 ...

  5. NModbus4的使用

    步骤1:打开串口 SerialPort port = new SerialPort("COM7") port.BaudRate = ; port.BaudRate = ; port ...

  6. Linux基础命令---间歇执行命令---watch

    [watch] watch指令可以间歇性的执行程序,将输出结果以全屏的方式显示,默认是2s执行一次. watch指令下发后,将会一直被执行,直到被中断. [语法] watch \ [-d h v t] ...

  7. Django2.2 连接mySQL数据库

    一.Django2.2连接数据库(踩雷) 首先,Django2.2自带的是sqlite3数据库,但我们学的是mysql,因此学着连接(在mysql环境搭建成功的情况下)---参考博客: https:/ ...

  8. redis缓存穿透00

    缓存穿透 缓存穿透,是指查询一个数据库一定不存在的数据.正常的使用缓存流程大致是,数据查询先进行缓存查询,如果key不存在或者key已经过期,再对数据库进行查询,并把查询到的对象,放进缓存.如果数据库 ...

  9. 入职一个月快速熟悉大型Vue项目经验感想

    来到和睦的公司家庭已经一个月出头了,从技术层面来说,公司项目PC端是我目前来说接触的最大最复杂的项目了,德老师也说这个不断开发更新迭代的项目的代码量相对于全国的web来说是蛮多的,对于快速熟悉这样的大 ...

  10. Ruby Rails正式学习:Ruby on Rails 做个演示项目吧,逐渐完善

    项目开始 一. 新建Rails项目 1. 修改一下Gemfile文件(简单修改一下) source 'https://rubygems.org' git_source(:github) { |repo ...