ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF1092E. Minimal Diameter Forest

2022-08-19 17:03:18  阅读:129  来源: 互联网

标签:Diameter CF1092E int max maxn using define Minimal first


\(\texttt{Difficulty:2000}\)

题意

给定 \(n(1\le n\le 1000)\) 个点, \(m(0\le m\le n-1)\) 条边组成的森林,现在增加一些边,是森林成为一棵树,并且其直径最小,求最小直径以及方案。

思路

考虑让森林中每一棵树的直径的中点为根,然后按每棵树最长链的长度 \(l_i\) 排序,不断将根连到最长链最长的树的根上,显然这样构造可以使直径最小,直径的值为每个子树的直径的最大值,\(l\) 最长的两个子树的 \(l\) 的和 \(+1\) ,\(l\) 第二,第三长两个子树的 \(l\) 的和 \(+2\) 这三者中的最大值, \(n\) 非常小,直接暴力 \(O(n^2)\) 即可解决。

代码

#include<bits/stdc++.h>
#include<unordered_map>
#include<unordered_set>
using namespace std;
using LL = long long;
using LD = long double;
using ULL = unsigned long long;
using PII = pair<int, int>;
using TP = tuple<int, int, int>;
#define all(x) x.begin(),x.end()
#define mst(x,v) memset(x,v,sizeof(x))
#define mul(x,y) (1ll*(x)*(y)%mod)
#define mk make_pair
//#define int LL
//#define double LD
#define lc tr[x].ch[0]
#define rc tr[x].ch[1]
#define endl '\n'
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
#pragma warning(disable : 4996)
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
const double eps = 1e-10;
const double pi = acos(-1);
const LL MOD = 1000000007;
const LL mod = 998244353;
const int maxn = 300010;

int N, M, root[maxn], tot = 0;
vector<int>G[maxn], T[maxn];
bool used[maxn];
vector<PII>E;

void add_edge(int from, int to)
{
	G[from].push_back(to);
	G[to].push_back(from);
}

int dfs(int v, int p, int d)
{
	int tmp = d;
	for (auto& to : G[v])
	{
		if (to == p)
			continue;
		tmp = max(tmp, dfs(to, v, d + 1));
	}
	return tmp;
}

int D[maxn], diameter = -inf, f[maxn];

void dfs(int v, int p)
{
	used[v] = true, T[tot].push_back(v);
	for (auto& to : G[v])
	{
		if (to == p)
			continue;
		dfs(to, v);
		diameter = max(diameter, D[v] + D[to] + 1);
		D[v] = max(D[v], D[to] + 1);
	}
}

void solve()
{
	for (int i = 1; i <= N; i++)
	{
		if (!used[i])
			root[++tot] = i, dfs(i, 0), f[tot] = diameter, diameter = -inf, mst(D, 0);
	}
	for (int i = 1; i <= tot; i++)
	{
		int tmp = inf;
		for (auto& v : T[i])
		{
			int num = dfs(v, 0, 0);
			if (num < tmp)
				tmp = num, root[i] = v;
		}
		E.push_back(PII(tmp, root[i]));
	}
	int ans = 0;
	for (int i = 1; i <= tot; i++)
		ans = max(ans, f[i]);
	sort(all(E)), reverse(all(E));
	if (tot >= 3)
		ans = max(ans, max(E[0].first + E[1].first + 1, E[1].first + E[2].first + 2));
	else if (tot == 2)
		ans = max(ans, E[0].first + E[1].first + 1);
	else
		ans = max(ans, E[0].first);
	cout << ans << endl;
	for (auto& [x, y] : E)
	{
		if (y == E[0].second)
			continue;
		cout << E[0].second << ' ' << y << endl;
	}
}

int main()
{
	IOS;
	cin >> N >> M;
	int u, v;
	for (int i = 1; i <= M; i++)
		cin >> u >> v, add_edge(u, v);
	solve();

	return 0;
}

标签:Diameter,CF1092E,int,max,maxn,using,define,Minimal,first
来源: https://www.cnblogs.com/Prgl/p/16602583.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有