反向建边的思路,感觉和题解写的差不多啊,但就是过不去
查看原帖
反向建边的思路,感觉和题解写的差不多啊,但就是过不去
181715
gjh303987897楼主2021/11/15 20:02
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#define maxn 500005
using namespace std;
int n,m,k,ans[maxn],vis[maxn],fa[maxn],x[maxn],y[maxn],bui[maxn];
int read(){
	int x=0,f=1; char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch<='9'&&ch>='0'){
		x=(x<<3)+(x<<1)+(ch^48);
		ch=getchar();
	}
	return x*f;
}
struct data{
	int next,to;
}t[maxn*2+1];
int head[maxn],js;
inline void add(int u,int v){
	t[++js].next=head[u];
	head[u]=js;
	t[js].to=v;
} 
int find(int r){
	if(fa[r]!=r) fa[r]=find(fa[r]);
	return fa[r];
}
void un(int r1,int r2){
	r1=find(r1); r2=find(r2);
	if(r1!=r2) fa[r2]=r1;
}
bool judge(int r1,int r2){
	r1=find(r1); r2=find(r2);
	if(r1!=r2) return false;
	else return true; 
}
int main()
{
	cin>>n>>m;//n=read(); m=read();
	
	for(int i=1;i<=m;i++){
		x[i]=read(); y[i]=read();
		add(x[i],y[i]); add(y[i],x[i]);
	}
	k=read(); for(int i=1;i<=n;i++) fa[i]=i;
	for(int i=1;i<=k;i++){
		bui[i]=read(); vis[bui[i]]=1;
	}
	ans[k+1]=n-k;
	for(int i=1;i<=m;i++){
		if(!vis[x[i]]&&!vis[y[i]]&&!judge(x[i],y[i])){
			un(x[i],y[i]); ans[k+1]--; 
		}
	}
   
	int que=ans[k+1];
	for(int i=k;i>=1;i--){
		vis[bui[i]]=0; que++;
		for(int j=head[bui[i]];j!=0;j=t[j].next){
			if(!vis[t[j].to]&&judge(bui[i],t[j].to)==false){
			un(bui[i],t[j].to); que--; 
		    }
		}
		ans[k]=que;
	}
	for(int i=1;i<=k+1;i++){
		cout<<ans[i]<<endl;
	} 
	return 0; 
}
2021/11/15 20:02
加载中...