Time Limit: 3 sec / Memory Limit: 1024 MiB
Score : 450 points
Problem Statement
You are given an undirected graph with N vertices and zero edges.
The vertices are numbered 1,2,...,N, and initially all vertices are white.
Process a total of Q queries of the following three types:
- Type 1 : Add an undirected edge connecting vertices u and v.
- Type 2 : If vertex v is white, change it to black; if it is black, change it to white.
- Type 3 : Determine whether a black vertex can be reached from vertex v by traversing zero or more edges; report
Yes
if reachable, andNo
otherwise.
Constraints
- All input values are integers.
- 1≤N≤
- 1≤Q≤
- Type 1 queries satisfy the following constraints:
- 1≤u<v≤N
- For each query, no edge connecting u and v has been added before that query.
- Type 2,3 queries satisfy the following constraints:
- 1≤v≤N
Input
The input is given from Standard Input in the following format:
N 𝑄
Query1
Query2
⋮
QueryQ
where Queryi represents the i-th query.
Type 1 queries are given in the following format:
1 u v
Type 2 queries are given in the following format:
2 v
Type 3 queries are given in the following format:
3 v
Output
For each type 3 query, output the answer as follows:
Yes
if a black vertex can be reached from vertex v by traversing zero or more edges;No
if no black vertex can be reached from vertex v by traversing zero or more edges.
Sample Input 1
cpp
5 12
3 2
2 2
3 2
1 2 5
1 3 4
3 4
3 5
1 4 5
1 1 3
3 1
2 2
3 1
Sample Output 1
No
Yes
No
Yes
Yes
No
In this input, the graph initially has five vertices and zero edges.
This input contains 12 queries.
- The 1st query is
3 2
.- At this point, no black vertex can be reached from vertex 2 by traversing zero or more edges, so report
No
.
- At this point, no black vertex can be reached from vertex 2 by traversing zero or more edges, so report
- The 2nd query is
2 2
.- Vertex 22 is white, so change it to black.
- The 3rd query is
3 2
.- At this point, black vertex 22 can be reached from vertex 2 by traversing zero or more edges. Therefore, report
Yes
.
- At this point, black vertex 22 can be reached from vertex 2 by traversing zero or more edges. Therefore, report
- The 4th query is
1 2 5
.- Add an edge connecting vertices 2,5.
- The 5th query is
1 3 4
.- Add an edge connecting vertices 3,4.
- The 6th query is
3 4
.- At this point, no black vertex can be reached from vertex 4 by traversing zero or more edges, so report
No
.
- At this point, no black vertex can be reached from vertex 4 by traversing zero or more edges, so report
- The 7th query is
3 5
.- At this point, black vertex 2 can be reached from vertex 5 by traversing zero or more edges. Therefore, report
Yes
.
- At this point, black vertex 2 can be reached from vertex 5 by traversing zero or more edges. Therefore, report
- The 8th query is
1 4 5
.- Add an edge connecting vertices 4,5.
- The 9th query is
1 1 3
.- Add an edge connecting vertices 1,3.
- The 10th query is
3 1
.- At this point, black vertex 2 can be reached from vertex 1 by traversing zero or more edges. Therefore, report
Yes
.
- At this point, black vertex 2 can be reached from vertex 1 by traversing zero or more edges. Therefore, report
- The 11th query is
2 2
.- Vertex 2 is black, so change it to white.
- The 12th query is
3 1
.- At this point, no black vertex can be reached from vertex 1 by traversing zero or more edges, so report
No
.
- At this point, no black vertex can be reached from vertex 1 by traversing zero or more edges, so report
思路分析
初始化:使用并查集(Union-Find)数据结构来管理连通分量。每个顶点初始时独立为一个分量,颜色均为白色,黑色计数为零。
处理查询:
类型1(添加边):合并两个顶点所在的连通分量,合并时黑色计数相加。
类型2(切换颜色):改变顶点颜色,并更新所在分量的黑色计数。白色变黑色时计数增加,黑色变白色时计数减少。
类型3(检查可达性):检查顶点所在分量的黑色计数是否大于零,若是则输出"Yes",否则输出"No"。
效率优化:并查集通过路径压缩和按秩合并优化,确保每次操作的时间复杂度接近常数,适用于大规模输入。
代码
cpp
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=2e5+5;
vector<int>fa(N),rankk(N,0),color(N,0),cnt_black(N,0);
int n,q,op,u,v;
int find(int x){
if(fa[x]!=x){
fa[x]=find(fa[x]);
}
return fa[x];
}
void unionset(int x,int y){
int rx=find(x),ry=find(y);
if(rx==ry)return;
if(rankk[rx]>rankk[ry]){
fa[ry]=rx;
cnt_black[rx]+=cnt_black[ry];
}
else{
if(rankk[rx]==rankk[ry])rankk[ry]++;
fa[rx]=ry;
cnt_black[ry]+=cnt_black[rx];
}
}
vector<int>black(N,0);
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n>>q;
for(int i=1;i<=n;i++){
fa[i]=i;
}
while(q--){
cin>>op;
if(op==1){
cin>>u>>v;
unionset(u,v);
}
else if(op==2){
cin>>v;
int c=color[v];
if(c==0){
color[v]=1;
int root=find(v);
cnt_black[root]++;
}
else{
color[v]=0;
int root=find(v);
cnt_black[root]--;
}
}
else{
cin>>v;
int root=find(v);
if(cnt_black[root]>0){
cout<<"Yes\n";
}
else{
cout<<"No\n";
}
}
}
return 0;
}