Submission #556910

# Submission time Handle Problem Language Result Execution time Memory
556910 2022-05-04T10:55:31 Z timreizin Flood (IOI07_flood) C++17
100 / 100
315 ms 23372 KB
#include <iostream>
#include <vector>
#include <algorithm>
#include <deque>
#include <set>
#include <string>
#include <numeric>
#include <cmath>
#include <cassert>
#include <array>
#include <numeric>

using namespace std;

struct Point
{
    array<int, 4> dir{-1, -1, -1, -1};
    int x, y;
};

int main()
{
    cin.tie(0)->sync_with_stdio(0);
    int n;
    cin >> n;
    vector<Point> points(n);
    for (Point &i : points) cin >> i.x >> i.y;
    int w;
    cin >> w;
    vector<int> adj(2 * w);
    vector<tuple<int, int, int>> segms(w);
    for (int i = 0; i < w; ++i)
    {
        int a, b;
        cin >> a >> b;
        --a;
        --b;
        segms[i] = {a, b, 0};
        //third value - where when comes in b
        if (points[a].x == points[b].x)
        {
            if (points[a].y > points[b].y) swap(a, b);
            get<2>(segms[i]) = 3;
            points[a].dir[1] = 2 * i;
            points[b].dir[3] = 2 * i + 1;
            //0 - up, right
            //1 - down, left
        }
        else
        {
            if (points[a].x > points[b].x) swap(a, b);
            get<2>(segms[i]) = 0;
            points[a].dir[2] = 2 * i;
            points[b].dir[0] = 2 * i + 1;
        }
        get<0>(segms[i]) = a;
        get<1>(segms[i]) = b;
        //a->b or
        //b
        //^
        //|
        //a
    }
    int cnt = 0;
    for (auto [a, b, c] : segms)
    {
        //2 * i, a->b
        for (int i = (c + 1) % 4; ; i = (i + 1) % 4)
        {
            if (points[b].dir[i] != -1)
            {
                adj[2 * cnt] = points[b].dir[i];
                break;
            }
        }
        //2 * i + 1, a<-b
        for (int i = (c + 3) % 4; ; i = (i + 1) % 4)
        {
            if (points[a].dir[i] != -1)
            {
                adj[2 * cnt + 1] = points[a].dir[i];
                break;
            }
        }
        ++cnt;
    }
    vector<int> used(2 * w, -1);
    auto dfs = [&adj, &used](auto self, int v, int face) -> void
    {
        used[v] = face;
        if (used[adj[v]] == -1) self(self, adj[v], face);
    };
    int counter = 0;
    for (int i = 0; i < 2 * w; ++i)
    {
        if (used[i] == -1)
        {
            dfs(dfs, i, counter);
            ++counter;
        }
    }
    vector<vector<pair<int, int>>> faces(counter);
    for (int i = 0; i < w; ++i)
    {
        faces[used[2 * i]].emplace_back(i, used[2 * i + 1]);
        faces[used[2 * i + 1]].emplace_back(i, used[2 * i]);
    }
    int start;
    set<pair<int, int>> hor, vert;
    {
        int left = -1, up = -1, i = 0;
        for (auto [a, b, c] : segms)
        {
            if (points[a].x == points[b].x)
            {
                vert.insert({points[a].x, i});
                //vertical
                if (left == -1)
                {
                    left = i;
                    ++i;
                    continue;
                }
                auto [a2, b2, c2] = segms[left];
                if (points[a].x < points[a2].x) left = i;
            }
            else
            {
                hor.insert({points[a].y, i});
                //horizontal
                if (up == -1)
                {
                    up = i;
                    ++i;
                    continue;
                }
                auto [a2, b2, c2] = segms[up];
                if (points[a].y > points[a2].y) up = i;
            }
            ++i;
        }
        if (left != -1) start = used[2 * left];
        else start = used[2 * up];
    }
    vector<int> saved = used;
    used = vector<int>(counter);
    vector<bool> isDel(w);
    while (!hor.empty() || !vert.empty())
    {
        int start;
        {
            if (!vert.empty()) start = saved[2 * (vert.begin()->second)];
            else start = saved[2 * (hor.begin()->second)];
        }
        vector<int> next{start};
        used[start] = 1;
        while (!next.empty())
        {
            set<int> nnext;
            for (int f : next)
            {
                for (auto [v, f2] : faces[f])
                {
                    if (!used[f2])
                    {
                        nnext.insert(f2);
                        isDel[v] = true;
                    }
                    auto [a, b, c] = segms[v];
                    if (points[a].x == points[b].x)
                    {
                        //vert
                        vert.erase({points[a].x, v});
                    }
                    else hor.erase({points[a].y, v});
                }
            }
            next.clear();
            for (int i : nnext)
            {
                next.push_back(i);
                used[i] = true;
            }
        }
    }
    vector<int> res;
    for (int i = 0; i < w; ++i) if (!isDel[i]) res.push_back(i + 1);
    cout << res.size() << '\n';
    for (int i : res) cout << i << '\n';
    return 0;
}
//1 - outer face
//0 - first inner
//3 - inner rect
//2 - left
/*
15
1 1
8 1
4 2
7 2
2 3
4 3
6 3
2 5
4 5
6 5
4 6
7 6
1 8
4 8
8 8
17
1 2
2 15
15 14
14 13
13 1
14 11
11 12
12 4
4 3
3 6
6 5
5 8
8 9
9 11
9 10
10 7
7 6
*/
/*
9
2 2
4 2
4 4
2 4
3 2
3 3
3 4
4 3
2 3
12
2 8
3 8
3 7
7 4
1 9
4 9
1 5
5 2
5 6
6 7
6 8
6 9
*/

Compilation message

flood.cpp: In function 'int main()':
flood.cpp:108:9: warning: variable 'start' set but not used [-Wunused-but-set-variable]
  108 |     int start;
      |         ^~~~~
# Verdict Execution time Memory Grader output
1 Correct 1 ms 212 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 1 ms 212 KB Output is correct
2 Correct 0 ms 212 KB Output is correct
3 Correct 0 ms 212 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 0 ms 212 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 0 ms 340 KB Output is correct
2 Correct 1 ms 340 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 1 ms 212 KB Output is correct
2 Correct 1 ms 212 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 1 ms 212 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 1 ms 340 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 1 ms 340 KB Output is correct
2 Correct 1 ms 340 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 1 ms 340 KB Output is correct
2 Correct 1 ms 340 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 20 ms 3172 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 69 ms 10952 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 84 ms 13276 KB Output is correct
2 Correct 280 ms 22560 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 239 ms 16592 KB Output is correct
2 Correct 251 ms 23372 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 315 ms 19392 KB Output is correct
2 Correct 86 ms 14864 KB Output is correct