Verificación de triangulación de diferentes colores, clasificación de ángulo interno

http://acm.zjnu.edu.cn/CLanguage/contests/1167/problems/1002.html
(se puede enviar en el DO de nuestra escuela)

Título

Ingrese una triangulación posiblemente incorrecta (polígono convexo de orden n, diagonales internas n-3).
El peso del borde de cada borde es uno de tres colores.

Verificación 1: Esta es una triangulación correcta
Verificación 2: Cada triángulo unitario de esta triangulación es un triángulo heterocromático.

Ideas

Si la triangulación es correcta, el ángulo interior de cada elemento del triángulo interior corresponde a una arista.
(A la inversa, una línea diagonal corresponde a dos ángulos internos, y un borde de contorno corresponde a un ángulo interno).
Si hay un error de conexión, el polígono interno está obligado a no ser un triángulo. De esta forma no se encontrará el lado correspondiente a la esquina interior.
Si cada triángulo es un triángulo heterocromático, entonces las dos esquinas de cada ángulo interior son de diferentes colores.

Así que simplemente enumere las esquinas interiores, verifique cada esquina interior, si existe el lado opuesto y si las esquinas incluidas son de diferentes colores.

¿Cómo enumerar las esquinas interiores?

Para construir esta figura geométrica en un modelo de teoría de grafos no dirigido, esperamos que el número en la lista de adyacencia de cada punto sea en sentido horario o antihorario, luego cada borde adyacente enumerado representa el ángulo interno en la figura.

Considere el número actual como el valor mínimo al ordenar la lista de adyacencia y reasigne todos los números (módulo). De esta manera, después de ordenar, naturalmente puede enumerar desde n-1 y el siguiente es 0 1 2 El
siguiente es un método de ordenación en sentido antihorario:
no entiende lambda, puede escribir una función de comparación y pasar i como una variable global.

 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;
     });
 }

Código


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";
    }
}

Supongo que te gusta

Origin blog.csdn.net/Tighway/article/details/108578237
Recomendado
Clasificación