连通 OR 不连通
Time Limit:1000MS Memory Limit:65536K
Total Submit:51 Accepted:9
Description
给定一个无向图,一共n个点,请编写一个程序实现三种操作:
E x 从原图中删除连接x节点的所有边。
D x y 从原图中删除连接x,y节点的边。
Q x y 询问x,y节点是否连通。
Input
输入只有一组测试数据:
第一行两个数n,m(5<=n<=40000,1<=m<=100000)
接下来m行,每行一对整数 x y (x,y<=n),表示x,y之间有边相连。保证没有重复的边。
接下来一行一个整数 q(q<=100000)
以下q行每行一种操作,保证不会有非法删除。
Output
按询问次序输出所有Q操作的回答,连通的回答Yes,不连通的回答No。
Sample Input
3 3
1 2
1 3
2 3
5
Q 1 2
E 2
Q 1 3
D 3 1
Q 1 3
Sample Output
Yes
Yes
No
Hint
输入数据较多,尽量用scanf和printf代替cin和cout!
Source
中文题意,很简单。
首先把所有的边加进来,记录所有的命令,并且执行所有的删除操作,然后逆序加边,并查集维护,有一个bug,被坑wa一次,就是一条边只能算第一次删除,以后的删除就不存在,例如有三个点,1 2 3 其中1-2,1-3,第一次执行删除1-2边的命令,第二次执行删除与1相连的所有边的命令,则第二次只删除了1-3边,在恢复边时,假如不考虑时间,则第一次恢复了1-2,1-3两条边,显然是错的。
代码:
/* ***********************************************
Author :rabbit
Created Time :2014/3/7 17:12:34
File Name :1.cpp
************************************************ */
#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <string>
#include <time.h>
#include <math.h>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define eps 1e-8
#define pi acos(-1.0)
typedef long long ll;
const int maxn=41000;
set<int> s[maxn],t[maxn];
int fa[maxn];
int find(int x){
if(fa[x]!=x)fa[x]=find(fa[x]);
return fa[x];
}
void bin(int a,int b){
int fx=find(a);
int fy=find(b);
if(fx==fy)return;
fa[fx]=fy;
}
struct OP{
char op;
int x,y;
}pp[110000];
int ans[110000];
map<int,int> mp;
int hash(int x,int y){
if(x>y)swap(x,y);
return mp[50000*x+y];
}
int shan(int x,int y,int i){
if(x>y)swap(x,y);
mp[50000*x+y]=i;
}
int main()
{
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
int n,m;
while(~scanf("%d%d",&n,&m)){
for(int i=1;i<=n;i++){
fa[i]=i;
s[i].clear();
}
int tot=0;
while(m--){
int u,v;
scanf("%d%d",&u,&v);
s[u].insert(v);
s[v].insert(u);
}
char op[5];
int Q;
scanf("%d",&Q);
mp.clear();
set<int>::iterator it;
for(int i=1;i<=Q;i++){
scanf("%s",op);
pp[i].op=op[0];
if(pp[i].op=='E'){
scanf("%d",&pp[i].x);
int x=pp[i].x;
for(it=s[x].begin();it!=s[x].end();it++){
int y=*it;
if(hash(x,y))continue;
shan(x,y,i);
}
}
else{
scanf("%d%d",&pp[i].x,&pp[i].y);
if(pp[i].op=='D')shan(pp[i].x,pp[i].y,i);
}
}
//cout<<"4444"<<endl;
for(int i=1;i<n;i++){
if(s[i].empty())continue;
for(it=s[i].begin();it!=s[i].end();it++){
int j=*it;
if(!hash(i,j))bin(i,j);
}
}
//cout<<"han"<<endl;
for(int i=Q;i>=1;i--){
if(pp[i].op=='Q'){
int fx=find(pp[i].x);
int fy=find(pp[i].y);
tot++;
if(fx==fy)ans[tot]=1;
else ans[tot]=0;
}
else if(pp[i].op=='D'){
bin(pp[i].x,pp[i].y);
}
else{
for(it=s[pp[i].x].begin();it!=s[pp[i].x].end();it++){
int x=pp[i].x;
int y=*it;
if(hash(x,y)==i)bin(x,y);
}
}
}
for(int i=tot;i>=1;i--){
if(ans[i])puts("Yes");
else puts("No");
}
}
return 0;
}