2020牛客多校第三场 Operating on a Graph

You are given a graph containing n vertices and m edges. Vertices are numbered from 0 to n-1. Initially, vertex i belongs to group i. We define a group A is connected to group B if and only if there exists at least an edge that connects the two vertices which belong to A and B respectively.

Now we will do q operations on this graph. The i-th operation is represented by an integer o_ioi​.

In i-th operation, if there are no vertices belong to group o_ioi​, nothing happens. Otherwise, for all vertices belong to a group which is connected to o_ioi​, those vertices will belong to group  o_ioi​ after this operation.

Now you are also given the q operations. Please answer each vertex belongs to which group after all operations.

输入描述:

The first line contains one integer t (1 \le t \le 1.6 \times 10^51≤t≤1.6×105) --- the number of test cases.

The first line of each test contains two positive integers n and m (2 \le n \le 8 \times 10^52≤n≤8×105, 1 \le m \le 8 \times 10^51≤m≤8×105) --- the number of vertices and edges in the given graph.

The following are m lines. Each of them contains two integers x and y, indicating there is an edge between vertex x and vertex y (0 \le x < y < n0≤x<y<n, there are no duplicate edges in the same test)

The following line contains one integer q (1 \le q \le 8 \times 10^51≤q≤8×105) -- the number of operations in this test. Then there is one more line contains q integers o_1, o_2, \ldots, o_qo1​,o2​,…,oq​ (0 \le o_i < n0≤oi​<n).

The sum of n across the test cases doesn't exceed 8 \times 10^58×105.


The sum of m across the test cases doesn't exceed 8 \times 10^58×105.

 

And the sum of q across the test cases doesn't exceed 8 \times 10^58×105.

输出描述:

For each test, output one line contains n integers --- the i-th integer of them representing the group that the vertex i-1 belongs to.

示例1

输入

复制

5
4 3
0 1
1 2
2 3
4
0 1 3 0
4 3
0 1
1 2
2 3
2
0 2
4 3
0 1
1 2
2 3
2
0 3
4 1
1 3
1
2
5 5
0 1
0 2
1 2
1 3
3 4
3
4 4 0

输出

复制

0 0 0 0
2 2 2 2
0 0 3 3
0 1 2 3
0 0 0 0 0

说明

 

Take the first test for example:

 

Initially, the four vertex is belong to 0, 1, 2, 3 respectively.

 

After the first operation, the four vertex is belong to 0, 0, 2, 3 respectively.


After the second operation, because there is no vertex belong to 1 now. The four vertex is still belong to 0, 0, 2, 3 respectively.
 

After the third operation, the four vertex is belong to 0, 0, 3, 3 respectively.


After the last operation, the four vertex is belong to 0, 0, 0, 0 respectively.

 

并查集 + list

听说list可以O(1)合并两个堆

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 8e5 + 5;
using namespace std;
vector<int> G[maxn];
list<int> lists[maxn];
int fa[maxn];
int n, m;
void init(){
    for(int i = 0; i < n; i++){
        fa[i] = i;
        lists[i].clear();
        lists[i].push_back(i);
        G[i].clear();
    }
}

int find(int x){
    if(x == fa[x])
        return x;
    return fa[x] = find(fa[x]);
}

void dfs(int x){
    if(x != find(x)){
        return ;
    }
    int sz = lists[x].size();
    while(sz--){
        int u = lists[x].front();
        lists[x].pop_front();
        for(auto i : G[u]){
            int uu = find(u);
            int ii = find(i);
            if(ii != uu){
                fa[ii] = uu;
                lists[uu].splice(lists[uu].end(), lists[ii]);
            }

        }
    }
}

void solve(){
    cin >> n >> m;
    init();
    for(int i = 1; i <= m; i++){
        int a, b;
        cin >> a >> b;
        G[a].push_back(b);
        G[b].push_back(a);
    }
    int k;
    cin >> k;
    for(int i = 1; i <= k; i++){
        int b;
        cin >> b;
        dfs(b);
    }
    for(int i = 0; i < n; i++){
        cout << find(i) << " ";
    }
    cout << endl;
}

int main(){
    ios::sync_with_stdio(0);
    int t;
    cin >> t;
    while(t--){
        solve();
    }
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值