CF1548A Web of Lies

CF1548A Web of Lies

强大的黄题,很有意思。

题意:一个点的权值是所有与他相邻的点中最小的,则这个点被删除,与之相连的所有边也被删除。三种操作:加边、删边和计算剩余点数。回答所有操作。

结论:一个点会被删的条件是至少一个直接朋友比自己强,所以只需记 \(out_i\) 表示 \(i\) 有几个比自己强的朋友。询问的答案就是 \(out_i = 0\) 的 \(i\) 的数量。修改时可以 \(O(1)\) 维护。时间复杂度 \(O(n)\)。

没想到的原因:一上来直接去想暴力修改了(STL神力),这种题还是得多玩两组数据才能观察出性质。

#include<bits/stdc++.h>
//#include<atcoder/all>
#define F(i,l,r) for(int i(l); i <= (r); ++ i)
#define G(i,r,l) for(int i(r); i >= (l); -- i)
#define mp make_pair
#define fi first
#define se second
#define pii pair<int, int>
using namespace std;
//using namespace atcoder;
using ll = long long;
const int N = 3e5;
const int mod = 1e9 + 7;
int n, m, q, ans = 0;
int out[N];
void Main(){
	cin >> n >> m;
	F(i, 1, m){
		int u, v;
		cin >> u >> v;
		if(u > v){
			++ out[v];
		}
		else{
			++ out[u];
		}
	}
	F(i, 1, n){
		if(out[i] == 0) ++ ans;
	}
	cin >> q;
	while(q --){
		int op;
		cin >> op;
		if(op == 1){
			int u, v;
			cin >> u >> v;
			if(u > v){
				if(out[v] == 0){
					-- ans;
				}
				++ out[v];
			}
			else{
				if(out[u] == 0){
					-- ans;
				}
				++ out[u];
			}
		}
		else if(op == 2){
			int u, v;
			cin >> u >> v;
			if(u > v){
				-- out[v];
				if(out[v] == 0){
					++ ans;
				}
			}
			else{
				-- out[u];
				if(out[u] == 0){
					++ ans;
				}
			}
		}
		else{
			cout << ans << '\n';
		}
	}
	return ;
}
signed main(){
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	int T = 1;
	while(T --) Main(); 
	return fflush(0), 0;
}
posted @ 2026-10-15 22:29  superl61  阅读(6)  评论(0)    收藏  举报