Operating on a Graph(并查集,区域染色)

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 oi.

In i-th operation, if there are no vertices belong to group oi , nothing happens. Otherwise, for all vertices belong to a group which is connected to oi, those vertices will belong to group oi 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 ≤ t ≤ 1.6 × 105) — the number of test cases.

The first line of each test contains two positive integers n and m (2 ≤ n ≤ 8 × 105, 1 ≤ 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 ≤ x < y < n, there are no duplicate edges in the same test)

The following line contains one integer q (1 ≤ q ≤ 8 × 105) – the number of operations in this test. Then there is one more line contains q integers o1,o2…oq(0 ≤ oi < n)

The sum of n across the test cases doesn’t exceed 8×105.

The sum of m across the test cases doesn’t exceed 8×105.

And the sum of q across the test cases doesn’t exceed 8×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.

输入

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.

题目大意

给定n点m边图,q个询问,每个询问为x颜色,若此时图上有x颜色的部分,这该部分临边的部分会被染成x颜色(有可能是一个点,有可能是同种颜色的子图)

代码实现
#include 

using namespace std;
const int maxn = 8e5 + 10;
int f[maxn];

int Find(int x) {
    return f[x] == x ? x : f[x] = Find(f[x]);
}

vector<int> g[maxn];

int main() {
    int T;
    scanf("%d", &T);
    while (T--) {
        int n, m;
        scanf("%d %d", &n, &m);
        for (int i = 0; i <= n; i++) {
            f[i] = i;
            g[i].clear();
        }
        for (int i = 1, u, v; i <= m; i++) {
            scanf("%d %d", &u, &v);
            g[u].push_back(v);
            g[v].push_back(u);
        }
        int q;
        scanf("%d", &q);
        while (q--) {
            int u;
            scanf("%d", &u);
            if (f[u] != u) {
                continue;
            }
            vector<int> p = g[u];
            g[u].clear();
            for (int i = 0; i < p.size(); i++) {
                // 更新相邻部分的根颜色节点
                int v = Find(p[i]);
                if (v != u) {
                    f[v] = u;
                    if (g[u].size() < g[v].size()) {
                        swap(g[u], g[v]);
                    }
                    for (int j = 0; j < g[v].size(); j++) {
                        g[u].push_back(g[v][j]);
                    }
                }
            }
        }
        for (int i = 0; i < n; i++) {
            printf("%d ", Find(i));
        }
        puts("");
    }
    return 0;
}

你可能感兴趣的:(图论)