#6102. 染色(Coloring)

染色(Coloring)

染色(Coloring)

题目描述

小杨同学有一张包含 nn 个结点的无向图 GGGG 中的结点依次以 1,2,,n1,2,\ldots,n 编号。

小杨同学发现 GG 中每个结点的度数都是 22。显然 GG 中恰好有 nn 条边。

小杨同学想为 GG 中的结点染色,使得任意一条边两端的结点都有不同的颜色。

小杨同学想知道最少需要多少种颜色才能在满足条件的前提下为 GG 染色。

输入格式

本题包含多组数据。

第一行,一个正整数 tt,表示数据组数。

对于每组数据:

第一行,一个正整数 nn,表示无向图 GG 中的结点数。

接下来 nn 行,每行两个正整数 ui,viu_i, v_i,表示一条连接结点 uiu_iviv_i 的无向边,整数之间以空格分隔。

保证 GG 中没有重边与自环。

输出格式

对于每组数据:输出一行,一个整数,表示在满足条件的前提下为 GG 染色需要的最少颜色数。

样例输入 #1

4
6
1 6
2 1
3 2
4 3
5 4
6 5
6
1 3
3 5
5 1
2 4
4 6
6 2
3
1 2
2 3
3 1
5
1 4
2 5
3 1
4 2
5 3

样例输出 #1

2
3
3
3

数据范围

对于 40%40\% 的测试点,保证 n500\sum n \le 500n\sum n 指每个输入中多组数据的 nn 的总和。

对于所有测试点,保证 1t1001 \le t \le 1003n1053 \le n \le 10^5n105\sum n \le 10^5。保证 GG 中没有重边与自环。

参考程序

#include <iostream>
#include <algorithm>
using namespace std;
int n;
int a[100010], b[100010], cnt[100010];
void solve() {
    cin >> n;
    for (int i = 1; i <= n; i++)
        a[i] = b[i] = cnt[i] = 0;
    for (int i = 1; i <= n; i++) {
        int u, v;
        cin >> u >> v;
        b[u] = a[u];
        a[u] = v;
        b[v] = a[v];
        a[v] = u;
    }
    bool flag = false;
    for (int i = 1; i <= n; i++) {
        if (cnt[i])
            continue;
        int u = i, last = a[u];
        int v = a[u] + b[u] - last;
        while (!cnt[v]) {
            cnt[v] = cnt[u] + 1;
            last = u;
            u = v;
            v = a[u] + b[u] - last;
        }
        if (cnt[i] % 2 != 0)
            flag = true;
    }
    if (flag)
        cout << 3 << endl;
    else
        cout << 2 << endl;
}
int main() {
    int t;
    cin >> t;
    while (t--)
        solve();
    return 0;
}