并查集 1002 tree
题意:中文题面
分析:(官方题解)把每条边权是1的边断开,发现每个点离他最近的点个数就是他所在的连通块大小.
开一个并查集,每次读到边权是0的边就合并.最后Ansi=size[findset(i)],sizeAns_i=size[findset(i)],sizeAnsi=size[findset(i)],size表示每个并查集根的size.
其实DFS也能过.
#include <cstdio> #include <cstring> #include <vector> using namespace std; typedef long long ll; const int N = 1e5 + 5; const int INF = 0x3f3f3f3f; struct DSU { int rt[N], sz[N]; void clear(void) { memset (rt, -1, sizeof (rt)); memset (sz, 0, sizeof (sz)); } int Find(int x) { return rt[x] == -1 ? x : rt[x] = Find (rt[x]); } void Union(int x, int y) { x = Find (x); y = Find (y); if (x == y) return ; rt[y] = x; sz[x] += sz[y] + 1; } }dsu; int n; int main(void) { int T; scanf ("%d", &T); while (T--) { dsu.clear (); scanf ("%d", &n); for (int u, v, w, i=1; i<n; ++i) { scanf ("%d%d%d", &u, &v, &w); if (!w) { dsu.Union (u, v); } } int ans = 0; for (int i=1; i<=n; ++i) { ans ^= (dsu.sz[dsu.Find (i)] + 1); } printf ("%d ", ans); } return 0; }