7-4 疫情防控(题型:给出一张图,支持两种操作:1: 删除一个点,2: 询问两个点是否连通。)[好题!经典,删点求连通性]

正着做时间复杂度太大了,我们可是反着做,先把所用要求的看成机场全部关闭,然后从后往前,一个一个打开机场。

这题也没必要思维定势跑图论最短路什么的,之间用并查集维护,看看而能否相同即可

总结:

观察到无法简单地维护“删除”这个操作,考虑将所有操作离线,逆序处理。即,先删除要删除的所有点,再倒着往里加点,顺便把询问处理掉,用并查集维护即可。

时间复杂度为:O(n+mlogn+qlogn)。

ACcode:

#include
using namespace std;
#define int long long 
#define inf 0x3f3f3f3f
const int N=5e4+10,M=2e5+10,Q=1010;
int n,m,d,fa[N];
bool book[N];
struct E{
	int u,v;
};
vectorg[N];
vectorq;
vectoralg,erap;
stackres;
void init(){
	for(int i=1;i<=n;i++) fa[i]=i;
}
int find(int x){
	return fa[x]==x?x:fa[x]=find(fa[x]);
}
void merge(int i,int j){
	int f1=find(i);
	int f2=find(j);
    if(f1!=f2) fa[f1]=f2;
}
void solve(){
   cin>>n>>m>>d;
   init();
   for(int i=1;i<=m;i++){
   	int u,v;
   	cin>>u>>v;
   	g[u].push_back(v);
   	g[v].push_back(u);
   }
   for(int i=1;i<=d;i++){
   	int c,qq;
   	cin>>c>>qq;
   	book[c]=true;
   	erap.push_back(c);
   	alg.push_back(qq);
   	for(int j=1;j<=qq;j++){
   		int u,v;
   		cin>>u>>v;
   		q.push_back({u,v});
	   }
   }
   for(int i=1;i<=n;i++){
   	if(!book[i]){
   		for(auto x:g[i])
   			if(!book[x]) merge(i,x);
	   }
   }
   for(int i=alg.size()-1;i>=0;i--){
   	int cnt=0;
   	for(int j=0;j

over~

你可能感兴趣的:(算法,c++,图论,数据结构,删点求连通性)