并查集进阶版

打印 上一主题 下一主题

主题 980|帖子 980|积分 2940



过关代码如下
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include<bits/stdc++.h>
  3. #include<unordered_set>
  4. using namespace std;
  5. int n, m;
  6. vector<int> edg[400005];
  7. int a[400005], be[400005]; // a的作用就是存放要摧毁
  8. int k;
  9. int fa[400005];
  10. int daan[400005];
  11. void add(int x, int y) {
  12.         edg[x].push_back(y);
  13.         edg[y].push_back(x);
  14. }
  15. int find(int x) {
  16.         if (x == fa[x]) return x;
  17.         return fa[x] = find(fa[x]);
  18. }
  19. void uni(int x, int y) {
  20.         int xx = find(x), yy = find(y);
  21.         if (xx == yy) return;
  22.         fa[xx] = yy;
  23. }
  24. int main() {
  25.         cin >> n >> m;
  26.         int l, r;
  27.         for (int i = 1; i <= m; i++) {
  28.                 cin >> l >> r;
  29.                 add(l, r); // 建立边
  30.         }
  31.         cin >> k;
  32.         for (int i = 1; i <= k; i++) {
  33.                 cin >> a[i];
  34.                 be[a[i]] = 1; // 标记为1,表示被摧毁
  35.         }
  36.         int ans = n-k; // 一开始的时候每个点都是一个块
  37.         // 初始化并查集
  38.         for (int i = 0; i <= n; i++) fa[i] = i;
  39.         // 开始区分联通分量
  40.         for (int i = 0; i < n; i++) {
  41.                 if (be[i]) continue;
  42.                 for (int u : edg[i]) {
  43.                         if (be[u]) continue;
  44.                         if (find(i) == find(u)) continue;
  45.                         uni(i, u);// 连接
  46.                         ans--;
  47.                 }
  48.         }
  49.         daan[k+1] = ans;
  50.         for (int i = k; i >= 1; i--) {
  51.                 //cout << "yes" << endl;
  52.                 int xiufu = a[i];
  53.                 ans++;
  54.                 be[xiufu] = 0;  // 恢复为1
  55.                 for (int u : edg[xiufu]) {
  56.                         if (be[u]) continue;
  57.                         if (find(u) == find(xiufu)) continue;
  58.                         ans--;
  59.                         uni(u, xiufu);
  60.                 }
  61.                 daan[i] = ans;
  62.         }
  63.         for (int i = 1; i <= k+1; i++) {
  64.                 cout << daan[i] << endl;
  65.         }
  66.         //cout << " now";
  67.         return 0;
  68. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

乌市泽哥

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表