@atcoder - ARC092F @ bordes de dos caras


@descripción@

Dado un grafo dirigido para cada cara una vez le preguntó:

Después de que la otra cara de esto, los componentes de la imagen original ningún impacto conectado firmemente?

El número de puntos N ≤ 1000, el número de aristas M ≤ 200.000.

El título original Portal.

@solución@

Ver el tiempo 5s, atrevida suposición tiempo complejidad O (NM).

Un borde u-> v invertir el impacto:
si este borde en los componentes fuertemente conectados (equivalente a la presencia de la ruta de acceso a v u), cuando el otro camino no existe de u a v, la tapa fuertemente conectados reduce.
Si no es así, cuando hay otro camino de u a v, el flip incrementado fuertemente conectada.

Eso es una ventaja para u-> v, necesitamos condenado a dos cosas: si existe un camino de v au; si hay otro camino de u a v.

Antes de que un violento O (NM) puede hacer, y no necesitan escribir también una fuerte conexión.
En cuanto a este último. Lo que consideramos otros medios de recorrido: Hay una forma de U como punto de partida y sin u, el primer borde de U> v el camino.

La figura completa, entonces la búsqueda de cada punto u, si este camino se determina para cada punto x de la primera cara es sólo uno.
Esto se puede encontrar hasta qué punto, debido a la situación de cada punto se actualiza dos veces (sólo uno, más de uno).

código @accepted @

#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

const int MAXN = 1000;
const int MAXM = 200000;

vector<int>G[MAXN + 5]; int to[MAXM + 5];
void addedge(int u, int i) {G[u].push_back(i);}

int tag[MAXN + 5], que[2*MAXN + 5];
bool ans1[MAXM + 5], ans2[MAXM + 5];

int n, m;
int main() {
    scanf("%d%d", &n, &m);
    for(int i=1;i<=m;i++) {
        int a; scanf("%d%d", &a, &to[i]);
        addedge(a, i);
    }
    for(int i=1;i<=n;i++) {
        for(int j=1;j<=n;j++) tag[j] = 0;
        int s = 1, t = 0;
        for(int p=0;p<G[i].size();p++)
            tag[que[++t] = to[G[i][p]]] = G[i][p];
        while( s <= t ) {
            int x = que[s++], y = tag[x];
            for(int p=0;p<G[x].size();p++) {
                int q = to[G[x][p]];
                if( q != i ) {
                    if( tag[q] != -1 ) {
                        if( tag[q] == 0 )
                            tag[que[++t] = q] = y;
                        else if( tag[q] != y )
                            tag[que[++t] = q] = -1;
                    }
                }
                else ans1[G[x][p]] = 1;
            }
        }
        for(int p=0;p<G[i].size();p++)
            if( tag[to[G[i][p]]] == -1 ) ans2[G[i][p]] = 1;
    }
    for(int i=1;i<=m;i++)
        puts(ans1[i] ^ ans2[i] ? "diff" : "same");
}

@ @ Detalles

Al igual que esta densa gráfica, la estrella con la memoria de almacenamiento de vectores más rápido (y más amigable caché) en comparación con la cadena anterior. En particular, esta constante problema de gran impacto.

En cuanto a la memoria caché es Gesha. . . De acuerdo con mi entrada THUWC2020 aprendido, probablemente, además de la memoria, CPU que tiene un espacio temporal más reciente llamada caché.
Si usted tiene acceso a un mismo elemento, a continuación, para almacenar en caché es muy amable, y por lo tanto será más rápido.

Supongo que te gusta

Origin www.cnblogs.com/Tiw-Air-OAO/p/12468758.html
Recomendado
Clasificación