Isomorfismo de grafo no dirigido (hash)

tema

Descripción del problema

Si un gráfico no dirigido se vuelve a etiquetar y es completamente consistente con otro gráfico no dirigido (es decir, para dos puntos cualesquiera, el borde entre ellos existe o no existe en ambos gráficos), entonces se dice que los dos gráficos no dirigidos son isomórficos. .

Dados dos gráficos no dirigidos con n puntos y m bordes, determine si los dos gráficos no dirigidos son isomorfos.

Entrada

Un número T en la primera línea significa que hay T grupos de datos (T <= 20).
Para cada grupo de datos:
dos números n, m en la primera línea, lo que significa que los dos gráficos no dirigidos que se van a determinar son n puntos ym puntos Borde (n <= 200, m <= 4000) Las
siguientes m filas, cada fila tiene dos números x, y, lo que significa que hay un borde que conecta el punto xy el punto y en el primer gráfico (1 <= x, y < = n) Las
siguientes m líneas, cada línea tiene dos números x, y, lo que indica que hay un borde que conecta el punto xy el punto y en el segundo gráfico (1 <= x, y <= n)

Salida

Para cada grupo de datos, si los dos gráficos no dirigidos son isomorfos, envíe "SÍ", de lo contrario, muestre "NO"

Entrada de muestra

4
5 6
1 2
1 3
1 5
4 1
2 3
5 4
3 1
5 4
3 4
2 3
3 5
1 2

5 6
1 2
1 3
1 5
4 1
2 3
5 4
3 1
5 4
3 4
2 3
3 5
1 4

3 2
1 2
2 3
2 1
1 3

4 3
1 2
2 3
3 4
1 2
1 3
1 4

Salida de muestra

SI
NO
SI
NO

análisis

  • Para ver si dos gráficos son isomórficos, se puede pensar en usar valores hash para determinar un gráfico.
  • Luego, para un gráfico, su valor hash solo debe estar relacionado con su estructura y no tiene nada que ver con la cantidad de puntos, por lo que pueden existir las siguientes reglas hash
    • Para cada punto, su valor hash es la suma de su peso y el peso de los "puntos adyacentes a él" (por supuesto, puede multiplicarlo por algún número y modularlo nuevamente).
    • Al principio, los pesos de todos los puntos son 1, y luego se realizan varios cambios, cada vez que los puntos se ordenan por el peso de la última vez, y luego el valor hash se modifica de acuerdo con las reglas anteriores.
    • Debido a la clasificación, el valor hash de este gráfico solo está relacionado con su estructura.
  • Después de muchos cambios, si los puntos en las dos gráficas tienen el mismo peso, entonces podemos considerarlos como isomorfos. (Por supuesto, si no tiene suerte, es posible que se quede atascado, así que cámbielo unas cuantas veces y haga que la operación hash sea un poco más complicada)

programa

#include <cstdio>
#include <algorithm>
#define For(G,x) for(int h=G.head[x],o=G.V[h]; h; o=G.V[h=G.to[h]])
#define N 205
#define M 4005
using namespace std;
struct Tu{
    int head[N],to[M*2],V[M*2],num;
    void Add(int x,int y){to[++num]=head[x],head[x]=num,V[num]=y;}
}A,B;
struct zzk{
   
   int id,v;} a[2][N],b[2][N];
int n,m,cnt,k,F=1,f1[2][N],f2[2][N];
bool cmp(zzk x,zzk y){
   
   return x.v<y.v;}

void Hash(){
    sort(a[cnt]+1,a[cnt]+n+1,cmp);
    sort(b[cnt]+1,b[cnt]+n+1,cmp);
    for (int i=1,u=a[cnt][i].id; i<=n; i++,u=a[cnt][i].id){
        k=f1[cnt][u]*18;        //随意弄个规则修改 Hash 值 
        For(A,u) k+=f1[cnt][o]*666233;
        a[cnt^1][i].id=u;
        f1[cnt^1][u]=a[cnt^1][i].v=k;
    }
    for (int i=1,u=b[cnt][i].id; i<=n; i++,u=b[cnt][i].id){
        k=f2[cnt][u]*18;        //用同一个规则修改 Hash 值 
        For(B,u) k+=f2[cnt][o]*666233;
        b[cnt^1][i].id=u;
        f2[cnt^1][u]=b[cnt^1][i].v=k;
    }
    cnt^=1;
}

int main(){
    for (int T=(scanf("%d",&T),T),uu,vv; T--; F=1){

        A.num=B.num=0;
        for (int i=1; i<=n; i++) A.head[i]=B.head[i]=0;

        scanf("%d%d",&n,&m);
        for (int i=1; i<=m; i++) scanf("%d%d",&uu,&vv),A.Add(uu,vv),A.Add(vv,uu);
        for (int i=1; i<=m; i++) scanf("%d%d",&uu,&vv),B.Add(uu,vv),B.Add(vv,uu);
        for (int i=1; i<=n; i++){
            a[0][i].id=a[1][i].id=b[0][i].id=b[1][i].id=i;
            f1[cnt][i]=a[cnt][i].v=f2[cnt][i]=b[cnt][i].v=1;
        }
        for (int i=1; i<=n; i++) Hash();    //多次变换 
        sort(a[cnt]+1,a[cnt]+n+1,cmp);
        sort(b[cnt]+1,b[cnt]+n+1,cmp);
        for (int i=1; i<=n; i++)
            if (a[cnt][i].v!=b[cnt][i].v) {F=0; break;}
        puts(F?"YES":"NO");
    }
}

Supongo que te gusta

Origin blog.csdn.net/jackypigpig/article/details/78413187
Recomendado
Clasificación