Undirected graph isomorphism (hash)

topic

Problem Description

If an undirected graph is relabeled and completely consistent with another undirected graph (that is, for any two points, the edge between them exists or does not exist in both graphs), then the two undirected graphs are said to be isomorphic .

Given two undirected graphs with n points and m edges, determine whether the two undirected graphs are isomorphic.

Input

A number T in the first line means that there are T groups of data (T<=20).
For each group of data:
two numbers n, m in the first line, which means that the two undirected graphs to be determined are n points and m points Edge (n<=200,m<=4000) The
next m rows, each row has two numbers x, y, which means that there is an edge connecting point x and point y in the first graph (1<=x,y< =n) The
next m lines, each line has two numbers x, y, indicating that there is an edge connecting point x and point y in the second graph (1<=x,y<=n)

Output

For each group of data, if the two undirected graphs are isomorphic, output "YES", otherwise output "NO"

Sample Input

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

Sample Output

YES
NO
YES
NO

analysis

  • To see whether two graphs are isomorphic, one can think of using hash values ​​to determine a graph.
  • Then for a graph, its hash value should only be related to its structure, and has nothing to do with the number of points, so there can be the following hash rules
    • For each point, its hash value is the sum of its weight and the weight of "points adjacent to it" (of course, you can multiply it by some number and modulate it again).
    • At first, the weights of all points are 1, and then multiple changes are performed, each time the points are sorted by the weight of the last time, and then the hash value is modified according to the above rules.
    • Due to the sorting, the hash value of this graph is only related to its structure.
  • After many changes, if the points in the two graphs have the same weight, then we can regard them as isomorphic. (Of course, if you are unlucky, you may be stuck, so change it a few times and make the hash operation a little more complicated)

program

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

Guess you like

Origin blog.csdn.net/jackypigpig/article/details/78413187