主题描述
重新标记一个无向图后,如果与另一个无向图完全匹配,也就是说,对于任意两点,如果两个图之间的边都存在或不存在,则两个无向图称为同构。
给出n个点的m条边的无向图,判定两个无向图是否同形。
输入输出
第1行的1个随机数t表示有t组的数据(T=20 )。
对于每组数据:
第1行的2个数n、m表示判定的2个无向图都是n个点m条的边(n=200,m=4000 ) )。
接着m行,各行有x、y的个数为2,这表示在第一个图中存在边缘连接点x和点y (1=x,y=n ) ) )。
接下来m行,各行中x、y的数量为2,表示在第2个图中存在边的连接点x和点y (1=x,y=n ) ) ) )。
输出
对于每个数据集,如果两个有向图相同,则输出“是”,否则输出“否”
样本输入
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
样本输出
是
否
是
否
分析两幅图是否为同形时,可以考虑使用thdz值决定一幅图。 那么,对于一个图,其thdz值应该只与其结构有关,而与点的编号无关。 因此,有以下thdz规则
对于每个点,其thdz值是其权重与“与其相邻的点”的权重之和。 当然,你可以再花点时间建模。 最初所有点的权重为1,然后进行多次变更操作,每次中先将点按上次权重排序,然后按照以上规则修改thdz值即可。 由于顺序排列,该图的thdz值只与其结构有关。 进行多次变更后,如果在两幅图中的点权重情况相同,我们就可以视为它们是同构的。 (当然运气不好的话可能会卡在卡上,所以多转换几次,让thdz操作也复杂一点吧(程序# include cstdio # include algorithm # define for (g,x ) ) o=g.v [ h=g.to [ h ] ] # definen 205 # definem 4005 usingnamespacestd; 结构tu { int head [ n ],to[M*2],V[M*2],num; voidadd(intx,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]; OOLCMP(zzkx,zzk y ) {return x.vy.v; }void Hash () ) sort ) a[cnt] n 1,a[cnt] n 1,cmp ); sort(b[CNT]1,b[cnt] n 1,cmp ); for(intI=1,u=a[cnt][i].id; i=n; I,u=a [ CNT ] [ I ].id ] { k=f1 [ CNT ] [ u ] * 18; 混列值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(intI=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(inttt=) Scanf )、t )、有意季节、vv; T----; f=1(a.num=b.num=0; for(intI=1; i=n; I ) A.head[i]=B.head[i]=0; scanf('%d%d ),n,m ); for(intI=1; i=m; I )扫描(“% d % d”、有意季节、vv )、A.Add )、vv、有意季节); for(intI=1; i=m; I )扫描(“% d % d”、有意季节、vv )、B.Add )、B.Add )、vv、有意季节); for(intI=1; i=n; I ) ) a(0) (I ).id=a )1).I ).id=b ) ).id=I; f1 [ CNT ] [ I ]=a [ CNT ] [ I ].v=F2 [ CNT ] [ I ]=b [ CNT ] [ I ].v=1; }for(intI=1; i=n; I )混列); //多次转换sort(a[CNT]1,a[cnt] n 1,cmp ); sort(b[CNT]1,b[cnt] n 1,cmp ); for(intI=1; i=n; I ) if ) a[CNT][I].v!=b[CNT][I].v]{f=0; 布雷克; }puts(f?' 是' : '否'; }