• [CF Contest] Web of Lies 题解


    题目描述

    给你一个 (n) 个点 (m) 条边的无向图,要求支持以下几种操作共 (q) 次:

    • 加入一条边 ((u,v))
    • 删除一条边 ((u,v))
    • 查询按照以下步骤对图进行操作后剩下的点的数量:删除所有与其相连的点编号都比其大的点和与该点相连的边,然后再次进行操作,直到删除点的数量为 (0) 为止。(该查询对图的结构不影响)

    数据范围:(1 le n,q le 2cdot 10^5, 0 le m le 2cdot 10^5)

    结论

    对于每一个点,只要有任意相邻的点编号大于它,那么该点一定会在最后一轮前被删除。

    证明

    采用反证法。假如一个有一个相邻点编号大于它,且其存活到了最后一轮。那么其必有一个相邻点小于它。其相邻点若没有编号比其更小的,那么其会在本轮被删除,那本轮不为最后一轮。其相邻点若有编号比其更小的,同样的逻辑也适用于该点。这样我们得到一个无限下降的论证,但编号小于起始点的点数量是有限的,所以产生了矛盾。得证。

    代码实现

    由于正常邻接表的边删除操作不是 (O(1)) 的,所以不能使用邻接表。

    我们可以考虑使用一个叫 alive 的数组来存储 “比编号为 (i) 的点编号大的其邻居的数目”,再使用一个变量 ans 存储每次询问的答案,由于初始所有点都是不连通的,那么 ans 初始化为 (n)

    • 假如一个点加边后有且仅有一个相邻的点编号大于它,答案就减少 (1)
    • 假如一个点删掉与它相邻且唯一的编号大于它的点,答案就增加 (1)

    代码

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    using namespace std;
    
    const int maxn = 2e5 + 5;
    int alive[maxn], n, m;
    
    int main() {
    	cin >> n >> m;
    	int ans = n;
    	for(int i = 1, x, y; i <= m; i ++) {
    		cin >> x >> y;
    		if(x > y) { 
    			alive[y] ++; 
    			if(alive[y] == 1)  ans --; 
    		} else { 
    			alive[x] ++; 
    			if(alive[x] == 1)  ans --; 
    		}
    	}
    	int q;
    	cin >> q;
    	while(q --) {
    		int cmd, x, y;
    		cin >> cmd;
    		if(cmd == 1) {
    			cin >> x >> y;
    			if(x > y) {          // when x is stronger than y
    				alive[y] ++;       // y's dangerous friend ++
    				if(alive[y] == 1) ans --;   // if this is the first dangerous friend, answer --;
    			} else { 
    				alive[x] ++; 
    				if(alive[x] == 1) ans --; 
    			}
    		} else if(cmd == 2) {
    			cin >> x >> y;
    			if(x > y) { 
    				alive[y] --; 
    				if(alive[y] == 0) ans ++; 
    			} else { 
    				alive[x] --; 
    				if(alive[x] == 0) ans ++; 
    			}
    		} else {
    			cout << ans << endl;
    		}
    	}
    }
    
  • 相关阅读:
    mysql 大数据量求平均值
    mysql 大数据量求平均值
    dhcpd.conf(5)
    dhcpd.conf(5)
    学习记录(文章内容来自相关材料)
    分享一个ASP.NET 文件压缩解压类 C#
    服务降级
    distinct用法
    trim合理和谐
    小娱乐一下,fileInfo中的Name ,FullName的用法小BUG
  • 原文地址:https://www.cnblogs.com/Inversentropir-36/p/15094242.html
Copyright © 2020-2023  润新知