diff --git a/TangDou/Topic/HuanGenDp/CF1406.cpp b/TangDou/Topic/HuanGenDp/CF1406.cpp index 3604f31..6560d67 100644 --- a/TangDou/Topic/HuanGenDp/CF1406.cpp +++ b/TangDou/Topic/HuanGenDp/CF1406.cpp @@ -1,9 +1,15 @@ #include using namespace std; -const int N = 1e5 + 10; +const int N = 1e5 + 10, M = N << 1; #define int long long #define endl "\n" +// 链式前向星 +int e[M], h[N], idx, w[M], ne[M]; +void add(int a, int b, int c = 0) { + e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++; +} + vector g[N]; // 邻接表,存图 int sz[N]; // sz[i]:以i为根的子树中节点个数 int son[N]; // son[i]:去掉节点i后,剩下的连通分量中最大子树节点个数 @@ -13,8 +19,10 @@ void dfs(int u, int fa) { sz[u] = 1; // u为根的子树中,最起码有一个节点u son[u] = 0; // 把节点u去掉后,剩下的连通分量中最大子树节点个数现在还不知道,预求最大,先设最小 - for (int i = 0; i < g[u].size(); i++) { // 枚举u的每一条出边 - int v = g[u][i]; + // for (int i = 0; i < g[u].size(); i++) { // 枚举u的每一条出边 + for (int i = h[u]; ~i; i = ne[i]) { + // int v = g[u][i]; + int v = e[i]; if (v == fa) continue; dfs(v, u); sz[u] += sz[v]; @@ -32,6 +40,10 @@ signed main() { // 多组测试数据,清空 memset(sz, 0, sizeof sz); memset(son, 0, sizeof son); + // 初始化链式前向星 + memset(h, -1, sizeof h); + idx = 0; + r1 = r2 = 0; for (int i = 0; i <= n + 10; i++) g[i].clear(); @@ -40,6 +52,7 @@ signed main() { cin >> x >> y; g[x].push_back(y); g[y].push_back(x); + add(x, y), add(y, x); } dfs(1, 0); // 以1号点为入口,它的父节点是0