数树
数树
https://ac.nowcoder.com/acm/contest/7509/D
思路:
可以从度的角度来考虑
来考虑相连
如果是两个D>1的结点相连,我们知道这一定是两颗树合并了,那么树++,如果其中一个D=1,那就是一个点和并到了一颗树上,树的个数不变,如果两个D=0的点相连,树的个数++
接下来考虑断开
如果是两个D>1的结点断开,我们知道肯定是1棵树变成了2颗树。如果其中一个D=1,那么就是把一个叶子结点分出去了,树的个数不变。如果两个点的度都为1,那么分成的两个东西都是单个结点,树的数目--
代码:
#include<bits/stdc++.h> using namespace std; const int maxn = 1e8+7; int n; int D[maxn]; map<pair<int, int >, int> mp; int main() { int ans = 0; cin >> n; for(int i = 1; i <= n; i++){ int type, u, v; cin >> type; if(type == 1){ cin >> u >> v; if(u > v) swap(u, v); pair<int, int> pi = make_pair(u, v); if(mp[pi]){ continue; } mp[pi] = 1; if(D[u] && D[v]){ ans--; //两棵树合并 } else if(D[u]==0 && D[v] == 0){ ans++; //两个结点连成一颗树 } D[u]++; D[v]++; } else if(type == 2){ cin >> u >> v; if(u > v) swap(u, v); pair<int, int> pi = make_pair(u, v); if(!mp[pi]){ continue; } mp[pi] = 0; if(D[u] > 1 && D[v] > 1){ ans++; } else if(D[u] == 1 && D[v] == 1){ ans--; } D[u]--; D[v]--; } else if(type == 3){ cout << ans << endl; } } }