数树
数树
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;
}
}
}
查看24道真题和解析
