GDCPC 2024 F Graph Solution Code

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int N = 1e5 + 10;
int n, m, rx, ry;
using vi = vector<int>;
class dsu
{
private:
    vi f;
    int n;
    int find(int x)
    {
        return x == f[x] ? x : f[x] = find(f[x]);
    }

public:
    dsu(int tn) : n(tn), f(tn + 1)
    {
        for (int i = 1; i <= tn; i++)
        {
            f[i] = i;
        }
    }
    bool conn(int x, int y)
    {
        return find(x) == find(y);
    }
    void merge(int x, int y)
    {
        if (conn(x, y))
            return;
        f[find(y)] = find(x);
    }
};
class graph
{
private:
    int n;
    dsu ds;
    vector<vi> road;
    vi f;

public:
    graph(int tn) : n(tn), ds(tn), road(tn + 1, vi{}), f(tn + 1, 0)
    {
    }
    bool disc(int x, int y)
    {
        return !ds.conn(x, y);
    }
    void insert(int x, int y)
    {
        ds.merge(x, y);
        road[x].push_back(y);
        road[y].push_back(x);
    }
    void init(int x)
    {
        for (auto &i : road[x])
        {
            if (i == f[x])
                continue;
            f[i] = x;
            init(i);
        }
    }
    void build(int rt)
    {
        f[rt] = rt;
        init(rt);
    }
    vi extract(int x, int y)
    {
        vi ret;
        while (x != y)
            ret.push_back(x), x = f[x];
        ret.push_back(y);
        return ret;
    }
};
class graphset
{
private:
    vector<graph> grph;

public:
    graphset(int n, int m) : grph((m + n - 2) / (n - 1), n) {}
    bool connect(int x, int y)
    {
        int l = 0, r = grph.size();
        while (l < r)
        {
            int mid = (l + r) >> 1;

            if (grph[mid].disc(x, y))
                r = mid;
            else
                l = mid + 1;
        }
        if (l < grph.size())
            grph[l].insert(x, y);
        return l >= grph.size() - 1;
    }
    void print(int x, int y)
    {
        printf("%d %d\n", x, y);
        for (auto &i : grph)
        {
            i.build(y);
            vi tmp = i.extract(x, y);
            printf("%d ", tmp.size());
            for (auto &j : tmp)
            {
                printf("%d ", j);
            }
            putchar('\n');
        }
    }
};
void run()
{
    scanf("%d%d", &n, &m);
    graphset gph(n, m);
    rx = ry = -1;
    for (int i = 1, x, y; i <= m; i++)
    {
        scanf("%d%d", &x, &y);
        if (!gph.connect(x, y))
            continue;
        rx = x, ry = y;
    }
    if (rx == ry)
    {
        puts("-1");
        return;
    }
    gph.print(rx, ry);
}
int main()
{
    int T = 1;
    scanf("%d", &T);
    while (T--)
        run();
}
posted @ 2024-05-31 23:27  丝羽绫华  阅读(13)  评论(0编辑  收藏  举报