1. 程式人生 > 其它 >牛客小白月賽42.F 火鳳燎原

牛客小白月賽42.F 火鳳燎原

火鳳燎原

題意

規定蒲公英為原樹上的一個連通塊,滿足:

  1. 有且一箇中心點。
  2. 設中心點在原樹中的度為 \(k(k \ge 3)\) ,則必須有 \(k-1\) 個結點在蒲公英上是一個葉子,剩下一條鏈,長度至少為 \(2\) (不包括中心點) 。

兩個蒲公英不相同,當且僅當存在一個點,在其中一個蒲公英上而不在另一個蒲公英上。

如圖為中心點 \(0\) 的一個蒲公英。

給定一棵無根樹,求書上的蒲公英數量。

分析

假設給定的樹結點數量為 \(n\)

對於某一個點,假設它的度為 \(d\) ,那麼把這個點作為中心點的數量一共有 \(n - d - 1\) 個。

證明:因為中心點定了,所以要使蒲公英不同,只能改變它的鏈,對於除了這 \(d+1\)

個點的任意其他一個點,一定能與這個連通塊的唯一一個點聯通形成一條鏈。並且路徑是唯一的,所以不同的鏈個數為 \(n - (d+1)\)

列舉每一箇中心點即可。

Code

#include <iostream>
using namespace std;

const int N = 500010;

int d[N];

int main ()
{
    cout.tie(0)->sync_with_stdio(0);
    int T; cin >> T; while(T--)
    {
        int n; cin >> n;
        for (int i = 1; i <= n; i ++ ) d[i] = 0;
        for (int i = 1; i < n; i ++ )
        {
            int u, v; cin >> u >> v;
            ++ d[u], ++ d[v];
        }
        long long ret = 0;
        for (int i = 1; i <= n; i ++ )
            if (d[i] >= 3) ret += n - d[i] - 1;
        cout << ret << endl;
    }
    return 0;
}