题解:P12749 [POI 2017 R2] 罢工 Strikes
P12749 [POI 2017 R2] 罢工 Strikes - 题解
题意简述:
给定一棵
思路:
乍一看可能没什么思路,一般情况下我们会使用并查集维护联通块数量,但这东西不能删节点,还需要
当删除节点
但是这样仍存在问题:怎样模拟?如果直接对边打标记,看似时间复杂度正确,实际上对于菊花图直接卡成
代码:
#include<bits/stdc++.h>
using namespace std;
vector<int> mp[500005];
int n,ans=1,q;
int d[500005],fa[500005];
bool vis[500005];
void dfs(int u,int f)
{
fa[u]=f;
for(int v:mp[u])
if(v!=f)
d[u]++,dfs(v,u);
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<n;i++)
{
int u,v;
cin>>u>>v;
mp[u].push_back(v);
mp[v].push_back(u);
}
vis[0]=1;//由于钦定1为根后,fa[1]为0,而0号节点不存在,所以打上标记,认为0一直是被删除的状态
dfs(1,0);
cin>>q;
while(q--)
{
int x;
cin>>x;
if(x>0)
{
vis[x]=1;
d[fa[x]]--;
ans+=d[x]-1+(!vis[fa[x]]);
}
else
{
x=-x;
vis[x]=0;
d[fa[x]]++;
ans-=d[x]-1+(!vis[fa[x]]);
}
cout<<ans<<"\n";
}
return 0;
}