BC 68 Tree

問題描述

有一個樹(n個點, n−1條邊的聯通圖),點標號從1~n,樹

的邊權是0或1.求離每個點最近的點個數(包括自己).

輸入描述

第一行一個數字T,表示T組數據.
對於每組數據,第一行是一個n,表示點個數,接下來n

−1,每行三個整數u,v,w,表示一條邊連接的兩個點和邊

權.
T=50,1≤n≤100000,1≤u,v≤n,0≤w≤1

輸出描述

對於每組數據,輸出答案.
考慮到輸出規模過大,設ansi​​表示第i個點的答案.你只

需輸出ans1 xor ans2 xor ans3.. xor ansn​​即可.

輸入樣例

1
3
1 2 0
2 3 1

輸出樣例

1

Hint

ans1=2
ans2=2
ans3=1

2 xor 2 xor 1 = 1, 因此輸出1.


首先因爲求的是距離最近的點的個數,自己與自己的距離爲0,

所以當前只有可能到某個點的距離爲0,距離纔是最近的,所以

就是求每個點所在連通塊的個數。

找點的時候注意要查找父節點的個數,因爲更新的是父節點的值。

#include <stdio.h>
#define LL long long
const int maxn = 100005;
int father[maxn];
int cnt[maxn];
void init ( int n )
{
    for ( int i = 1; i <= n; i ++ )
        father[i] = i, cnt[i] = 1;
}
int find ( int x )
{
    int r = x;
    while ( father[r] != r )
        r = father[r];
    int i = x;
    while ( i != r )
    {
        int j = father[i];
        father[i] = r;
        i = j;
    }
    return r;
}
void merge ( int x, int y )
{
    int fx = find ( x ), fy = find ( y );
    if ( fx != fy )
    {
        father[fx] = fy;
        cnt[fy] += cnt[fx]; //就算賦值也沒用,只有父節點會實時更新
    }
}
int main ( )
{
    int T, n, u, v, w;
    scanf ( "%d", &T );
    while ( T -- )
    {
        scanf ( "%d", &n );
        init ( n );
        for ( int i = 0; i < n-1; i ++ )
        {
            scanf ( "%d%d%d", &u, &v, &w );
            if ( w == 0 )   //權值爲0就合併
                merge ( u, v );
        }
        int ans = 0;
        for ( int i = 1; i <= n; i ++ )
            ans ^= cnt[ find ( i ) ];   //連通塊大小
        printf ( "%I64d\n", ans );
    }
    return 0;
}


發佈了20 篇原創文章 · 獲贊 21 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章