比赛描述
输入
第一行两个数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]); } }