求助
  • 板块灌水区
  • 楼主Three_no
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/11/20 13:33
  • 上次更新2023/11/20 17:46:39
查看原帖
求助
1044332
Three_no楼主2023/11/20 13:33

给定一个无向图,请编写一个程序实现以下两种操作:

(1)D x y,从原图中删除连接x和y顶点的边。

(2)Q x y,询问x和y顶点是否连通。 Input 第一行两个数n,m(5<=n,m<=500000),分别表示顶点和边数。

接下来m行,每行一个整数x和y,表示x和y之间有边相连,保证没有重复的边。

接下来一行一个整数q(q<=500000)。

以下q行,每行一个操作,保证不会有非法删除。

Output 按询问次序输出所有Q操作的回答,连通的回答“C”,不连通的回答“D”。

3 3 1 2 1 3 2 3 5 Q 1 2 D 1 2 Q 1 2 D 3 2 Q 1 2 Sample Output C C D

【数据及时间和空间限制】

对于20%的数据,有m,q<=1000;

对于50%的数据,有m,q<=100000;

对于100%的数据,有m,q<=500000;

时间限制3秒,空间限制为256M。

超时求助

#include<cstdio>
#include<iostream>
#include<cstring>  
#include<map>  
#include<algorithm>
#define N 100007 
using namespace std;
int fa[N],m,n; 
map<int, bool> map1; 
int find(int x){
	if(fa[x]==x) return x;
	else return fa[x]=find(fa[x]);
}
void merge(int x,int y){
	x=find(x);
	y=find(y);
	if(x==y) return;
	fa[x]=y;
}
struct node{
	int u,v;
	bool flag;
}d[N],d2[N];
char ans[N];
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		fa[i]=i;
	}
	for(int i=1;i<=m;i++){
		scanf("%d%d",&d[i].u,&d[i].v);
		if(d[i].u>d[i].v) swap(d[i].u,d[i].v);
	}
	int q;
	scanf("%d",&q);
	for(int i=1;i<=q;i++){
		char f;
		cin>>f;
		scanf("%d%d",&d2[i].u,&d2[i].v);
		if(d2[i].u>d2[i].v) swap(d2[i].u,d2[i].v);
		if(f=='D'){
			d2[i].flag=true;
			map1[d2[i].u*N+d2[i].v]=true;
		}else d2[i].flag=false;
	}
	for(int i=1;i<=m;i++){
		if(!map1[d[i].u*N+d[i].v]){
			merge(d[i].u,d[i].v);
		}
	}
	int c=0;
	for(int i=q;i>=1;i--){
		if(d2[i].flag) merge(d2[i].u,d2[i].v);
		else{  
            if(find(d2[i].u)==find(d2[i].v)) ans[++c]='C';  
            else ans[++c]='D';  
        } 
	}
	for(int i=c;i>=1;i--){
		printf("%c\n", ans[i]);
	}

	return 0;
}

2023/11/20 13:33
加载中...