Different color triangulation check internal angle sorting

http://acm.zjnu.edu.cn/CLanguage/contests/1167/problems/1002.html
(can be submitted in our school OJ)

Title

Enter a possibly wrong triangulation (convex polygon of order n, internal n-3 diagonals).
The edge weight of each edge is one of three colors.

Verification 1: This is a correct triangulation.
Verification 2: Each unit triangle of this triangulation is a heterochromatic triangle.

Ideas

If the triangulation is correct, the inner angle of each element triangle inside corresponds to an edge.
(Conversely, a diagonal line corresponds to two internal angles, and a contour edge corresponds to one internal angle.)
If there is a connection error, the internal polygon is bound to be not a triangle. In this way, the side corresponding to the inner corner will not be found.
If each triangle is a heterochromatic triangle, then the two corners of each interior angle are of different colors.

So just enumerate the inner corners, check each inner corner, whether the opposite side exists, and whether the included corners are of different colors.

How to enumerate inner corners?

To build this geometric figure into an undirected graph theory model, we hope that the number in the adjacency list of each point is clockwise or counterclockwise, then each enumerated adjacent edge represents the internal angle in the figure.

Consider the current number as the minimum value when sorting the adjacency list and remap all numbers (modulo). In this way, after sorting, you can naturally enumerate from n-1 and the next is 0 1 2 The
following is a counterclockwise sorting method:
do not understand lambda, you can write a comparison function and pass i as a global variable.

 for (int i = 0; i < n; ++i) {
    
    
     sort(g[i].begin(), g[i].end(), [&i](edge l, edge r) {
    
    
         return (l.id - i + n) % n < (r.id - i + n) % n;
     });
 }

Code


const int MAXN = 2e5 + 59;
using pii = pair<int, int>;

int n;
char s[MAXN];
vector<pii> g[MAXN];
set<pii> has;

void solve(int kaseId = -1) {
    
    
    int _ = 0;
    cin >> _;
    cin >> n >> s;

    bool check1 = true;
    bool check2 = true;

    for (int i = 0; i < n - 3; ++i) {
    
    
        int u, v, c;
        cin >> u >> v >> c;
        u--, v--;
        g[u].emplace_back(v, c);
        g[v].emplace_back(u, c);
        has.emplace(u, v);
    }

    for (int i = 0; i < n; ++i) {
    
    
        int u = i;
        int v = (i + 1) % n;
        int c = s[i] - '0';
        g[u].emplace_back(v, c);
        g[v].emplace_back(u, c);
    }

    for (int i = 0; i < n; ++i) {
    
    
        sort(g[i].begin(), g[i].end(), [&i](pii l, pii r) {
    
    
            return (l.first - i + n) % n < (r.first - i + n) % n;
        });
    }

    for (int u = 0; check1 && u < n; ++u) {
    
    
        int len = int(g[u].size());
        for (int i = 0, j = 1; j < len; ++i, ++j) {
    
    
            int vi = g[u][i].first;
            int vj = g[u][j].first;
            int ci = g[u][i].second;
            int cj = g[u][j].second;

            if ((vi + 1) % n != vj &&
                (vj + 1) % n != vi &&   // 轮廓边必然存在,跳过。
                has.count(pii{
    
    vi, vj}) == 0 &&
                has.count(pii{
    
    vj, vi}) == 0) {
    
    
                check1 = false;
                break;
            }
            
            if (ci == cj) {
    
    
                check2 = false;
            }
        }
    }

    if (!check1) {
    
    
        cout << "neispravna triangulacija\n";
    } else if (!check2) {
    
    
        cout << "neispravno bojenje\n";
    } else {
    
    
        cout << "tocno\n";
    }
}

Guess you like

Origin blog.csdn.net/Tighway/article/details/108578237