P1197 [JSOI2008] 星球大战

星球大战题解:逆向思维与并查集应用

解题思路

这道题目要求我们处理动态删除节点后的连通块数量问题。直接处理删除操作比较困难,因此采用逆向思维:从最后的状态开始,逐步添加被删除的节点,计算连通块的变化。

关键步骤

  1. 逆向处理:从所有星球都被删除的状态开始,逐步添加被删除的星球

  2. 并查集维护:使用并查集数据结构高效维护连通块

  3. 预处理:标记将被删除的星球,初始化最终状态的连通块数量

代码注释

#include<bits/stdc++.h>
#define pii pair<int,int>
using namespace std;

const int N = 4e5 + 10;
int f[N]; // 并查集父节点数组
vector<int> g[N]; // 邻接表存储图的连接关系
pii t[N]; // 存储所有边的数组
int vis[N]; // 标记星球是否被摧毁 (1表示被摧毁)
int bad[N]; // 存储将被摧毁的星球顺序
int ans[N]; // 存储每个阶段的答案
int n, m, q; // n-星球数, m-边数, q-摧毁次数

// 并查集查找函数(带路径压缩)
int find(int x) {
    if(f[x] != x) f[x] = find(f[x]);
    return f[x];
}

// 并查集合并函数
void merge(int x, int y) {
    int fx = find(x), fy = find(y);
    f[fy] = fx; // 将fy的父节点设为fx
}

int main() {
    cin >> n >> m;
    
    // 初始化并查集
    for(int i = 0; i < n; i++) f[i] = i;
    
    // 读入图的边关系并构建邻接表
    for(int i = 1; i <= m; i++) {
        int x, y; 
        cin >> x >> y;
        g[x].push_back(y);
        g[y].push_back(x);
        t[i] = {x, y}; // 存储边
    }
    
    // 读入将被摧毁的星球
    cin >> q;
    for(int i = 1; i <= q; i++) {
        cin >> bad[i];
        vis[bad[i]] = 1; // 标记为将被摧毁
    }
    
    // 初始状态:所有未被摧毁的星球单独成块
    ans[q + 1] = n - q; 
    
    // 预处理:构建最终状态(所有被标记星球已摧毁)
    for(int i = 1; i <= m; i++) {
        int x = t[i].first, y = t[i].second;
        // 如果两个星球都未被摧毁,且不在同一连通块
        if(!vis[x] && !vis[y] && find(x) != find(y)) {
            merge(x, y); // 合并
            ans[q + 1]--; // 连通块数量减少
        }
    }
    
    // 逆向处理:逐个添加被摧毁的星球
    for(int i = q; i >= 1; i--) {
        int x = bad[i]; // 当前要恢复的星球
        vis[x] = 0; // 标记为未摧毁
        ans[i] = ans[i + 1] + 1; // 初始假设新增一个连通块
        
        // 遍历该星球的所有邻居
        for(int y : g[x]) {
            // 如果邻居未被摧毁且不在同一连通块
            if(!vis[y] && find(x) != find(y)) {
                merge(x, y); // 合并
                ans[i]--; // 连通块数量减少
            }
        }
    }
    
    // 输出结果:从初始状态到最终状态
    for(int i = 1; i <= q + 1; i++) 
        cout << ans[i] << endl;
    
    return 0;
}

 

posted @ 2025-04-23 21:29  CRt0729  阅读(30)  评论(0)    收藏  举报