柿子饼同学 发表于 2024-6-22 19:09:45

[心之碎片][0622] - 巡逻

本帖最后由 柿子饼同学 于 2024-6-22 19:30 编辑

巡逻 link
提交 4 次
3 h

知识点
dp求树的直径 贪心


思路
K == 0, ans0 = 2*(n - 1)
K == 1, 取直径1, ans1 = ans0 - 直径1 + 1
K == 2, 直径上的边权变成 -1, 再算直径2, ans2 = ans1 - 直径2 + 1
这里取反边权是因为, 第二条边如果覆盖了直径, 路程反而会增加这一段的, 别的路径不碍事
求直径就相当于求让路径可以尽可能减小的路程
O(n)

注意点
dfs 不能处理负权树求直径 , 只能用 dp 求, 写的时候 dp 写反了 , 要注意是用 ed 求出 u 的值
证明取直径最优 :
调整法 分两种情况讨论:一:若选的第一个环与直径无相交的边,则第二个环选直径最优,这等价于第一个环选直径。二:若选的第一个环与直径有相交的边,将直径与第二个环相交但不与第一个环相交的部分加到第一个环上,答案不变,然后再在第一个环上加上直径上不与第二个环重叠的点,答案增加,因此不如第一个环就直接选直径。综上,第一个环选直径一定不劣。
代码#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 5;

int n, k, ans;
vector<int> e;
int p, q, f, d;
bitset<N> isd;

void dfs(int u, int pa, int & id){
    for(auto ed : e){
      if(ed == pa) continue;
      f = u;
      if(isd && isd) d = d - 1;
      else d = d + 1;

      if(d <= d){
            d = d;
            id = ed;
      }

      dfs(ed, u, id);
    }   
}

void Getd1(){
    d = 0, f = 0, d = 0;
    dfs(1, 0, p);
    d = 0, d = 0, f = 0;
    dfs(p, 0, q);
}

int dp, res;
void Getd2(int u, int f){
    for(auto ed : e){
      if(ed == f) continue;
      int w = 1;
      if(isd && isd) w = -1;
      Getd2(ed, u);
      res = max(res, dp + dp + w);
      dp = max(dp, dp + w);
    }
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    cin >> n >> k;
    for(int i = 1; i < n; i++){
      int x, y;
      cin >> x >> y;
      e.emplace_back(y);
      e.emplace_back(x);
    }

    ans = 2*(n - 1);
    if(k == 0){
      cout << ans;
      return 0;
    }

    Getd1();   
    ans -= d - 1;
    if(k == 1){
      cout << ans;
      return 0;
    }

    for(int i = q; i; i = f){
      isd = 1;
    }
    Getd2(1, 0);
    ans -= res - 1;
    cout << ans;

    return 0;
}


ZZxxccvvbbnnmm 发表于 2024-6-26 20:34:42

Qwsazx 发表于 2024-6-26 20:34:55

AAssddffgghhjjk 发表于 2024-6-26 20:35:08

Poklmn 发表于 2024-6-26 20:35:19

PPooiiuuyyttrre 发表于 2024-6-26 20:35:29

Mnklpo 发表于 2024-6-26 20:35:39

QQQAAAXXX 发表于 2024-6-26 20:35:52

LLkkjjhhggffdds 发表于 2024-6-26 20:36:05

MMnnbbvvccxxzz 发表于 2024-6-26 20:36:22

harryhan123 发表于 2024-7-2 18:31:58

页: [1]
查看完整版本: [心之碎片][0622] - 巡逻