蒟蒻65分求助
查看原帖
蒟蒻65分求助
42627
youyou2007楼主2021/11/18 20:57

思路:

对于 k = 1 的情况,先求一遍树的直径,图用vector带边权的结构体存储(这个 30pts30pts 蒟蒻做出来了)

对于 k = 2 的情况,在前面的答案基础上,先遍历一遍树直径上的边,然后把那个边的边权置 1-1(由于是双向边,所以我双向都置了1-1),然后用 dfs2 这个函数求新图上的树的直径,更新答案

求树的直径用的方法是两遍 dfsdfs

可总是调不对,球球大佬们请教/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;
}
2021/11/18 20:57
加载中...