南邮 OJ 1584 连通 OR 不连通

连通 OR 不连通

时间限制(普通/Java) :  2000 MS/ 6000 MS          运行内存限制 : 65536 KByte
总提交 : 81            测试通过 : 25 

比赛描述

给定一个无向图,一共n个点,请编写一个程序实现两种操作:
D x y 从原图中删除连接x,y节点的边。
Q x y 询问x,y节点是否连通

输入

第一行两个数n,m(5<=n,m<=100000)
接下来m行,每行一对整数 x y (x,y<=n),表示x,y之间有边相连。保证没有重复的边。
接下来一行一个整数 q(q<=100000)
以下q行每行一种操作,保证不会有非法删除。

输出

按询问次序输出所有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

样例输出

C
C
D

提示

 

题目来源




/* AC 241MS
#include<iostream>
#include<set>
using namespace std;

#define N 100001
int f[N];

struct conet{
	int x,y;
}c[N],d[N];

bool operator<(const conet &c1,const conet &c2){
	return c1.x==c2.x ? c1.y<c2.y : c1.x<c2.x;
}

char op[N],r[N];

void init(int n){
	int i;
	for(i=1;i<=n;i++){
		f[i] = i;
	}
}

int father(int i){
	return f[i]==i ? i : f[i]=father(f[i]);
}

void connect(int i,int j){
	int fi,fj;
	fi = father(i);
	fj = father(j);
	if(fi != fj){
		f[fj] = fi;
	}
}

int main(){
	int n,m,i,q;
	set<conet> cs;
	scanf("%d%d",&n,&m);
	init(n);
	for(i=0;i<m;i++){
		scanf("%d%d",&c[i].x,&c[i].y);
		if(c[i].x > c[i].y){
			swap(c[i].x,c[i].y);
		}
	}
	scanf("%d",&q);
	for(i=0;i<q;i++){
		getchar();
		scanf("%c%d%d",op+i,&d[i].x,&d[i].y);
		if(d[i].x >d[i].y){
			swap(d[i].x,d[i].y);
		}
		if('D'==op[i]){
			cs.insert(d[i]);
		}
	}
	for(i=0;i<m;i++){
		if(!cs.count(c[i])){
			connect(c[i].x,c[i].y);
		}
	}
	int rNo=0;
	for(i=q-1;i>=0;i--){
		if('Q'==op[i]){
			if(father(d[i].x)==father(d[i].y)){
				r[rNo++]='C';
			}else{
				r[rNo++]='D';
			}
		}else{
			connect(d[i].x,d[i].y);
		}
	}
	for(i=rNo-1;i>=0;i--){
		printf("%c\n",r[i]);
	}
}
*/

/*
#include<iostream>

#define N 100001
int f[N];
bool flag[1000000];	//Memory Limit Exceed
struct conet{
	int x,y;
}c[N],d[N];

bool operator<(const conet &c1,const conet &c2){
	return c1.x==c2.x ? c1.y<c2.y : c1.x<c2.x;
}

char op[N],r[N];

void init(int n){
	int i;
	for(i=1;i<=n;i++){
		f[i] = i;
	}
}

int father(int i){
	return f[i]==i ? i : f[i]=father(f[i]);
}

void connect(int i,int j){
	int fi,fj;
	fi = father(i);
	fj = father(j);
	if(fi != fj){
		f[fj] = fi;
	}
}

int getNum(){
	int t, res;
	while((t = getchar()) < '0' || t >'9');
	res = t - '0';
	while((t = getchar()) >= '0' && t <= '9'){
		res = res * 10 + t - '0';
	}
	return res;
}

int main(){
	int n,m,i,q;
//	scanf("%d%d",&n,&m);
	n = getNum();
	m = getNum();
	init(n);
	for(i=0;i<m;i++){
//		scanf("%d%d",&c[i].x,&c[i].y);
		c[i].x = getNum();
		c[i].y = getNum();
		if(c[i].x > c[i].y){
			std::swap(c[i].x,c[i].y);
		}
	}
//	scanf("%d",&q);
	q = getNum();
	for(i=0;i<q;i++){
//		getchar();
//		scanf("%c%d%d",op+i,&d[i].x,&d[i].y);
		op[i] = getchar();
		d[i].x = getNum();
		d[i].y = getNum();
		if(d[i].x >d[i].y){
			std::swap(d[i].x,d[i].y);
		}
		if('D'==op[i]){
			flag[d[i].x*N+d[i].y] = 1;
		}
	}
	for(i=0;i<m;i++){
		if(!flag[c[i].x*N+c[i].y]){
			connect(c[i].x,c[i].y);
		}
	}
	int rNo=0;
	for(i=q-1;i>=0;i--){
		if('Q'==op[i]){
			if(father(d[i].x)==father(d[i].y)){
				r[rNo++]='C';
			}else{
				r[rNo++]='D';
			}
		}else{
			connect(d[i].x,d[i].y);
		}
	}
	for(i=rNo-1;i>=0;i--){
		printf("%c\n",r[i]);
	}
}
*/


#include<iostream>
#include<set>
using namespace std;

#define N 100001
int f[N];

struct conet{
	int x,y;
}c[N],d[N];

bool operator<(const conet &c1,const conet &c2){
	return c1.x==c2.x ? c1.y<c2.y : c1.x<c2.x;
}

char op[N],r[N];

void init(int n){
	int i;
	for(i=1;i<=n;i++){
		f[i] = i;
	}
}

int father(int i){
	return f[i]==i ? i : f[i]=father(f[i]);
}

void connect(int i,int j){
	int fi,fj;
	fi = father(i);
	fj = father(j);
	if(fi != fj){
		f[fj] = fi;
	}
}

int getNum(){
	int t, res;
	while((t = getchar()) < '0' || t >'9');
	res = t - '0';
	while((t = getchar()) >= '0' && t <= '9'){
		res = res * 10 + t - '0';
	}
	return res;
}

int main(){
	int n,m,i,q;
	set<conet> cs;
//	scanf("%d%d",&n,&m);
	n = getNum();
	m = getNum();
	init(n);
	for(i=0;i<m;i++){
//		scanf("%d%d",&c[i].x,&c[i].y);
		c[i].x = getNum();
		c[i].y = getNum();
		if(c[i].x > c[i].y){
			swap(c[i].x,c[i].y);
		}
	}
//	scanf("%d",&q);
	q = getNum();
	for(i=0;i<q;i++){
//		getchar();
//		scanf("%c%d%d",op+i,&d[i].x,&d[i].y);
		op[i] = getchar();
		d[i].x = getNum();
		d[i].y = getNum();
		if(d[i].x >d[i].y){
			swap(d[i].x,d[i].y);
		}
		if('D'==op[i]){
			cs.insert(d[i]);
		}
	}
	for(i=0;i<m;i++){
		if(!cs.count(c[i])){
			connect(c[i].x,c[i].y);
		}
	}
	int rNo=0;
	for(i=q-1;i>=0;i--){
		if('Q'==op[i]){
			if(father(d[i].x)==father(d[i].y)){
				r[rNo++]='C';
			}else{
				r[rNo++]='D';
			}
		}else{
			connect(d[i].x,d[i].y);
		}
	}
	for(i=rNo-1;i>=0;i--){
		printf("%c\n",r[i]);
	}
}


你可能感兴趣的:(ACM,or,连通,南邮OJ,不连通)