K. Problem K. Road Network

传送门:https://nanti.jisuanke.com/t/44347

这个题目 是说添加一条边让形成的环最大,那么就可以求一条树上的最长链,也就是树的直径。

1 DFS+DP

2 两次DFS

#include <iostream>
#include <malloc.h>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cmath>
#include <string>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <sstream>
#include <cstring>
#define IO                       \
    ios::sync_with_stdio(false); \
    // cin.tie(0);                  \
    // cout.tie(0);
using namespace std;
typedef unsigned long long uLL;
typedef long long LL;
const int maxn = 1e5 + 10;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const double PI = 3.14159;
const double eps = 1e-8;
struct Edge
{
    int before;
    int to;
} e[maxn];
int k, ans, head[maxn];
void add(int u, int v)
{
    e[k].before = head[u];
    e[k].to = v;
    head[u] = k++;
}
int DFS(int x, int fa)
{
    int tmp, mx = 0, mx2 = 0; //最长链与次长链初始化为0,如果链为负数我们不如不要
    for (int i = head[x]; i != -1; i = e[i].before)
    {
        int v = e[i].to;
        if (v != fa)
        {
            tmp = DFS(v, x);
            if (tmp > mx)
                mx2 = mx, mx = tmp;
            else if (tmp > mx2)
                mx2 = tmp;
        }
    }
    ans = max(ans, mx + mx2 + 1);
    return mx + 1; //最长链可以继续上传更新答案,但最长链和次长链连接起来不能上传
}
int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("in.txt", "r", stdin);
    // freopen("out.txt", "w", stdout);
#endif
    IO;
    int T, n, x, y;
    cin >> T;
    while (T--)
    {
        memset(head, -1, sizeof head);
        k = 0;
        cin >> n;
        for (int i = 0; i < n - 1; i++)
        {
            cin >> x >> y;
            add(x, y);
            add(y, x);
        }
        ans = -inf;
        DFS(1, 0);
        cout << n - ans << endl;
    }
    return 0;
}
发布了81 篇原创文章 · 获赞 29 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_44115065/article/details/104996687