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;
}

浙公网安备 33010602011771号