help,未过样例,思路为并查集+前后缀
查看原帖
help,未过样例,思路为并查集+前后缀
172136
spencer楼主2023/7/12 22:30
#include<bits/stdc++.h>
using namespace std;

int n,q,a[5000][5000],b[5000][5000];//a,b分别存储前缀和后缀
struct node{
    int x,y;
}rec[5000];
int finda(int t,int k){
	if(a[t][k]==k)return k;
	return a[t][k]=finda(t,a[t][k]);
}
void mergea(int t,int x,int y){
    int x1=finda(t,x),y1=finda(t,y);
    if(x1>y1)swap(x1,y1);
	a[t][y1]=x1;
}
int findb(int t,int k){
	if(b[t][k]==k)return k;
	return b[t][k]=findb(t,b[t][k]);
}
void mergeb(int t,int x,int y){
    int x1=findb(t,x),y1=findb(t,y);
    if(x1>y1)swap(x1,y1);
	b[t][y1]=x1;
}
int main(){
    int x,y,n,m;
	cin>>n>>m;
	for(int i=1;i<=m;i++){
        for(int j=1;j<=n;j++){
            a[i][j]=b[i][j]=j;//初始化
        }
    }
	for(int i=1;i<=m;i++){
		cin>>x>>y;
        rec[i].x=x;
        rec[i].y=y;
    }
    
    for(int i=1;i<=m;i++){
        mergea(i,rec[i].x,rec[i].y);//处理并查集前缀
    }
    for(int i=m;i>0;i--){
    	mergeb(i,rec[i].x,rec[i].y);//处理并查集后缀
	}
	cin>>q;
    int l,r;
    for(int i=1;i<=q;i++){
        cin>>l>>r;
        int ans=0,p[5000];
        for(int j=1;j<=n;j++){
            p[j]=min(a[l-1][j],b[r+1][j]);
        }
        for(int k=1;k<=n;k++){
            if(p[k]==k)ans++;
        }
        cout<<ans<<'\n';
    }
	return 0;
}

2023/7/12 22:30
加载中...