思路:
对于 k = 1
的情况,先求一遍树的直径,图用vector
带边权的结构体存储(这个 30pts 蒟蒻做出来了)
对于 k = 2
的情况,在前面的答案基础上,先遍历一遍树直径上的边,然后把那个边的边权置 −1(由于是双向边,所以我双向都置了−1),然后用 dfs2
这个函数求新图上的树的直径,更新答案
求树的直径用的方法是两遍 dfs
可总是调不对,球球大佬们请教/kel
// by youyou2007 Nov.
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
#include <stack>
#include <map>
#define rep(i, x, y) for(register int i = x; i <= y; i++)
#define per(i, x, y) for(register int i = x; i >= y; i--)
#define lc (k << 1)
#define rc (k << 1 | 1)
using namespace std;
const int N = 100005;
int n;
int k;
struct node{
int v, w;
};
vector <node> g[N];
int b[N], dep[N], ans;
int sum[N], fa[N];
void dfs(int x)
{
for(int i = 0; i < g[x].size(); i++)
{
int xx = g[x][i].v;
if(!b[xx])
{
b[xx] = 1;
dep[xx] = dep[x] + 1;
fa[xx] = x;
dfs(xx);
}
}
}
void dfs2(int x)
{
for(int i = 0; i < g[x].size(); i++)
{
int xx = g[x][i].v;
int ww = g[x][i].w;
if(!b[xx])
{
b[xx] = 1;
sum[xx] = sum[x] + ww;
dfs2(xx);
}
}
}
int main()
{
scanf("%d%d", &n, &k);
rep(i, 1, n - 1)
{
int x, y;
scanf("%d%d", &x, &y);
g[x].push_back({y, 1});
g[y].push_back({x, 1});
}
b[1] = 1;
dfs(1);
int temp = -1, tempp = 0;
rep(i, 1, n)
{
if(dep[i] > temp)
{
temp = dep[i];
tempp = i;
}
}
memset(b, 0, sizeof b);
memset(dep, 0, sizeof dep);
b[tempp] = 1;
dfs(tempp);
int temppp = -1;
temp = -1;
rep(i, 1, n)
{
if(dep[i] > temp)
{
temp = dep[i];
temppp = i;
}
}
ans = 2 * (n - 1) - (temp - 1);
if(k == 1)
{
printf("%d", ans);
return 0;
}
int now = temppp;
while(now != tempp)
{
for(int i = 0; i < g[fa[now]].size(); i++)
{
int xx = g[fa[now]][i].v;
if(xx == now)
{
g[fa[now]][i].w = -1;
break;
}
}
for(int i = 0; i < g[now].size(); i++)
{
int xx = g[now][i].v;
if(xx == fa[now])
{
g[now][i].w = -1;
break;
}
}
now = fa[now];
}
memset(b, 0, sizeof b);
memset(sum, 0, sizeof sum);
b[1] = 1;
temp = 0;
tempp = -1;
dfs2(1);
rep(i, 1, n)
{
if(sum[i] >= temp)
{
temp = sum[i];
tempp = i;
}
}
memset(b, 0, sizeof b);
memset(sum, 0, sizeof sum);
b[tempp] = 1;
dfs2(tempp);
temp = 0;
rep(i, 1, n)
{
if(sum[i] > temp)
{
temp = sum[i];
}
}
if(temp == 0)
{
printf("%d", ans + 1);
}
else
{
printf("%d", ans - (temp - 1));
}
return 0;
}