每次求出最长链更新答案后要将最长链上的边权改为-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 ;
}

最新文章

  1. hbase 简单操作
  2. CefSharp 初用遇到的一些问题及解决方法
  3. dede文章调用时过滤调 body里面的style属性和值
  4. 使用JPA TOOLS从数据库生成Entity文件
  5. Ios学习
  6. Android的读写文件权限
  7. Js模板引擎mustache
  8. SEO高手在扯蛋?
  9. 通过qsort(void * lineptr[], int left, int rifht, int (*comp)(void *, void *))解读指针函数和void指针
  10. JavaWeb之session
  11. 201521123023《Java程序设计》第10周学习总结
  12. node.js stream
  13. js 移动端上拉加载下一页通用方案
  14. nginx配置支持http2
  15. 关于笔记本安装parrot和kali的一些问题(花屏,息屏,屏幕不能休眠)
  16. 导入大数据量sql时候超时的问题
  17. 基于SurfaceView的可拖动视频控件
  18. 【php增删改查实例】第二十六节 - 个人详情页制作
  19. Kibana简介及下载安装
  20. for in和for of

热门文章

  1. Go package(2) strings 用法
  2. elasticsearch-head-master下运行npm install报npm WARN elasticsearch-head@0.0.0 license should be a valid SPDX license expression
  3. redhat网卡设置
  4. LeetCode.1108-使IP地址无效(Defanging an IP Address)
  5. OKR工作法 目标明确的写下来 - 结果记录- 校准
  6. GIT命令总结,so easy
  7. (已解决)Could not open &#39;/var/lib/nova/mnt/*/volume-*&#39;: Permission denied
  8. PDF技术(四)-Java实现Html转PDF文件
  9. 注入(Injection)
  10. py2 json字符串转字典去掉前缀u