Loading [MathJax]/extensions/tex2jax.js

P4380:「USACO18OPEN」Multiplayer Moo S – 题解

主要思路

这个题有点 nb。

按道理来讲直接做第二问得要 \(\Theta(n^4)\) 的时间,而且看上去也没有什么搞头。我们考虑处理出所有的接壤位置 \( (x, y, c_a, c_y) \) 代表颜色为 \(c_x\) 、编号 \(x\) 的点和颜色为 \(c_y\) 、编号 \(y\) 的点接壤。这样的接壤位置只有 \(\Theta(n^2)\) 个,所以我们分类出来之后再用并查集搞即可。

代码

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// P4380.cpp
#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 255;
int n, mat[MAX_N][MAX_N], mem[MAX_N * MAX_N], siz[MAX_N * MAX_N], ntot, psiz[MAX_N * MAX_N];
bool appear[MAX_N * MAX_N];
struct node
{
int x, y, colx, coly;
bool operator<(const node &rhs) const { return colx < rhs.colx || (colx == rhs.colx && coly < rhs.coly); }
} nodes[MAX_N * MAX_N * MAX_N];
int getId(int x, int y) { return (x - 1) * n + y; }
bool check(int x, int y) { return x <= n && x >= 1 && y <= n && y >= 1; }
int find(int x) { return x == mem[x] ? x : mem[x] = find(mem[x]); }
void newNode(int x, int y, int colx, int coly)
{
if (colx > coly)
swap(x, y), swap(colx, coly);
nodes[++ntot] = node{x, y, colx, coly};
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
scanf("%d", &mat[i][j]), mem[getId(i, j)] = getId(i, j);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
{
if (check(i - 1, j) && mat[i][j] == mat[i - 1][j] && find(getId(i, j)) != find(getId(i - 1, j)))
mem[find(getId(i, j))] = find(getId(i - 1, j));
if (check(i, j - 1) && mat[i][j] == mat[i][j - 1] && find(getId(i, j)) != find(getId(i, j - 1)))
mem[find(getId(i, j))] = find(getId(i, j - 1));
}
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
siz[find(getId(i, j))]++;
int ans1 = 0, ans2 = 0;
memcpy(psiz, siz, sizeof(siz));
for (int i = 1; i <= n * n; i++)
ans1 = max(ans1, siz[i]);
printf("%d\n", ans1);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
{
if (check(i - 1, j) && mat[i][j] != mat[i - 1][j])
newNode(find(getId(i, j)), find(getId(i - 1, j)), mat[i][j], mat[i - 1][j]);
if (check(i, j - 1) && mat[i][j] != mat[i][j - 1])
newNode(find(getId(i, j)), find(getId(i, j - 1)), mat[i][j], mat[i][j - 1]);
}
sort(nodes + 1, nodes + 1 + ntot);
for (int i = 1; i <= ntot; i++)
{
vector<int> idx;
idx.push_back(nodes[i].x), idx.push_back(nodes[i].y);
appear[nodes[i].x] = appear[nodes[i].y] = true;
if (find(nodes[i].x) != find(nodes[i].y))
{
psiz[find(nodes[i].y)] += psiz[find(nodes[i].x)];
mem[find(nodes[i].x)] = find(nodes[i].y);
}
while (i + 1 <= ntot && nodes[i + 1].colx == nodes[i].colx && nodes[i + 1].coly == nodes[i].coly)
{
i++;
if (!appear[nodes[i].x])
appear[nodes[i].x] = true, idx.push_back(nodes[i].x);
if (!appear[nodes[i].y])
appear[nodes[i].y] = true, idx.push_back(nodes[i].y);
if (find(nodes[i].x) != find(nodes[i].y))
{
psiz[find(nodes[i].y)] += psiz[find(nodes[i].x)];
mem[find(nodes[i].x)] = find(nodes[i].y);
}
}
for (int i = 0, siz_ = idx.size(); i < siz_; i++)
ans2 = max(ans2, psiz[idx[i]]);
for (int i = 0, siz_ = idx.size(); i < siz_; i++)
mem[idx[i]] = idx[i], psiz[idx[i]] = siz[idx[i]], appear[idx[i]] = false;
}
printf("%d\n", ans2);
return 0;
}
// P4380.cpp #include <bits/stdc++.h> using namespace std; const int MAX_N = 255; int n, mat[MAX_N][MAX_N], mem[MAX_N * MAX_N], siz[MAX_N * MAX_N], ntot, psiz[MAX_N * MAX_N]; bool appear[MAX_N * MAX_N]; struct node { int x, y, colx, coly; bool operator<(const node &rhs) const { return colx < rhs.colx || (colx == rhs.colx && coly < rhs.coly); } } nodes[MAX_N * MAX_N * MAX_N]; int getId(int x, int y) { return (x - 1) * n + y; } bool check(int x, int y) { return x <= n && x >= 1 && y <= n && y >= 1; } int find(int x) { return x == mem[x] ? x : mem[x] = find(mem[x]); } void newNode(int x, int y, int colx, int coly) { if (colx > coly) swap(x, y), swap(colx, coly); nodes[++ntot] = node{x, y, colx, coly}; } int main() { scanf("%d", &n); for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) scanf("%d", &mat[i][j]), mem[getId(i, j)] = getId(i, j); for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) { if (check(i - 1, j) && mat[i][j] == mat[i - 1][j] && find(getId(i, j)) != find(getId(i - 1, j))) mem[find(getId(i, j))] = find(getId(i - 1, j)); if (check(i, j - 1) && mat[i][j] == mat[i][j - 1] && find(getId(i, j)) != find(getId(i, j - 1))) mem[find(getId(i, j))] = find(getId(i, j - 1)); } for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) siz[find(getId(i, j))]++; int ans1 = 0, ans2 = 0; memcpy(psiz, siz, sizeof(siz)); for (int i = 1; i <= n * n; i++) ans1 = max(ans1, siz[i]); printf("%d\n", ans1); for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) { if (check(i - 1, j) && mat[i][j] != mat[i - 1][j]) newNode(find(getId(i, j)), find(getId(i - 1, j)), mat[i][j], mat[i - 1][j]); if (check(i, j - 1) && mat[i][j] != mat[i][j - 1]) newNode(find(getId(i, j)), find(getId(i, j - 1)), mat[i][j], mat[i][j - 1]); } sort(nodes + 1, nodes + 1 + ntot); for (int i = 1; i <= ntot; i++) { vector<int> idx; idx.push_back(nodes[i].x), idx.push_back(nodes[i].y); appear[nodes[i].x] = appear[nodes[i].y] = true; if (find(nodes[i].x) != find(nodes[i].y)) { psiz[find(nodes[i].y)] += psiz[find(nodes[i].x)]; mem[find(nodes[i].x)] = find(nodes[i].y); } while (i + 1 <= ntot && nodes[i + 1].colx == nodes[i].colx && nodes[i + 1].coly == nodes[i].coly) { i++; if (!appear[nodes[i].x]) appear[nodes[i].x] = true, idx.push_back(nodes[i].x); if (!appear[nodes[i].y]) appear[nodes[i].y] = true, idx.push_back(nodes[i].y); if (find(nodes[i].x) != find(nodes[i].y)) { psiz[find(nodes[i].y)] += psiz[find(nodes[i].x)]; mem[find(nodes[i].x)] = find(nodes[i].y); } } for (int i = 0, siz_ = idx.size(); i < siz_; i++) ans2 = max(ans2, psiz[idx[i]]); for (int i = 0, siz_ = idx.size(); i < siz_; i++) mem[idx[i]] = idx[i], psiz[idx[i]] = siz[idx[i]], appear[idx[i]] = false; } printf("%d\n", ans2); return 0; }
// P4380.cpp
#include <bits/stdc++.h>

using namespace std;

const int MAX_N = 255;

int n, mat[MAX_N][MAX_N], mem[MAX_N * MAX_N], siz[MAX_N * MAX_N], ntot, psiz[MAX_N * MAX_N];
bool appear[MAX_N * MAX_N];

struct node
{
    int x, y, colx, coly;
    bool operator<(const node &rhs) const { return colx < rhs.colx || (colx == rhs.colx && coly < rhs.coly); }
} nodes[MAX_N * MAX_N * MAX_N];

int getId(int x, int y) { return (x - 1) * n + y; }

bool check(int x, int y) { return x <= n && x >= 1 && y <= n && y >= 1; }

int find(int x) { return x == mem[x] ? x : mem[x] = find(mem[x]); }

void newNode(int x, int y, int colx, int coly)
{
    if (colx > coly)
        swap(x, y), swap(colx, coly);
    nodes[++ntot] = node{x, y, colx, coly};
}

int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            scanf("%d", &mat[i][j]), mem[getId(i, j)] = getId(i, j);
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
        {
            if (check(i - 1, j) && mat[i][j] == mat[i - 1][j] && find(getId(i, j)) != find(getId(i - 1, j)))
                mem[find(getId(i, j))] = find(getId(i - 1, j));
            if (check(i, j - 1) && mat[i][j] == mat[i][j - 1] && find(getId(i, j)) != find(getId(i, j - 1)))
                mem[find(getId(i, j))] = find(getId(i, j - 1));
        }
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            siz[find(getId(i, j))]++;
    int ans1 = 0, ans2 = 0;
    memcpy(psiz, siz, sizeof(siz));
    for (int i = 1; i <= n * n; i++)
        ans1 = max(ans1, siz[i]);
    printf("%d\n", ans1);
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
        {
            if (check(i - 1, j) && mat[i][j] != mat[i - 1][j])
                newNode(find(getId(i, j)), find(getId(i - 1, j)), mat[i][j], mat[i - 1][j]);
            if (check(i, j - 1) && mat[i][j] != mat[i][j - 1])
                newNode(find(getId(i, j)), find(getId(i, j - 1)), mat[i][j], mat[i][j - 1]);
        }
    sort(nodes + 1, nodes + 1 + ntot);
    for (int i = 1; i <= ntot; i++)
    {
        vector<int> idx;
        idx.push_back(nodes[i].x), idx.push_back(nodes[i].y);
        appear[nodes[i].x] = appear[nodes[i].y] = true;
        if (find(nodes[i].x) != find(nodes[i].y))
        {
            psiz[find(nodes[i].y)] += psiz[find(nodes[i].x)];
            mem[find(nodes[i].x)] = find(nodes[i].y);
        }
        while (i + 1 <= ntot && nodes[i + 1].colx == nodes[i].colx && nodes[i + 1].coly == nodes[i].coly)
        {
            i++;
            if (!appear[nodes[i].x])
                appear[nodes[i].x] = true, idx.push_back(nodes[i].x);
            if (!appear[nodes[i].y])
                appear[nodes[i].y] = true, idx.push_back(nodes[i].y);
            if (find(nodes[i].x) != find(nodes[i].y))
            {
                psiz[find(nodes[i].y)] += psiz[find(nodes[i].x)];
                mem[find(nodes[i].x)] = find(nodes[i].y);
            }
        }
        for (int i = 0, siz_ = idx.size(); i < siz_; i++)
            ans2 = max(ans2, psiz[idx[i]]);
        for (int i = 0, siz_ = idx.size(); i < siz_; i++)
            mem[idx[i]] = idx[i], psiz[idx[i]] = siz[idx[i]], appear[idx[i]] = false;
    }
    printf("%d\n", ans2);
    return 0;
}

 

Leave a Reply

Your email address will not be published. Required fields are marked *