给定一个无向图,请编写一个程序实现以下两种操作:
(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;
}