链接:
https://www.nowcoder.com/acm/contest/139/D
题意:
两个无向简单图都有n(1≤n≤8)个顶点,图G1有m1条边,图G2有m2条边,问G2有多少个子图与G1同构。
分析:
枚举所有的映射方案,再判断合法性,把每一合法映射所用到的边状态压缩一下,装到集合里去重即可。
代码:
1 import java.io.*; 2 import java.util.*; 3 4 public class Main { 5 Scanner cin = new Scanner(new BufferedInputStream(System.in)); 6 final int UP = 8 + 5; 7 int n, map[] = new int[99], cor[] = new int[UP]; 8 boolean G[][] = new boolean[UP][UP], G2[][] = new boolean[UP][UP]; 9 boolean opt[] = new boolean[UP]; 10 HashSet<Integer> set = new HashSet<Integer>(); 11 12 void init() { 13 for(int r = 0; r < UP; r++) 14 for(int c = 0; c < UP; c++) G[r][c] = G2[r][c] = false; 15 } 16 17 void dfs(int d) { 18 if(d == n + 1) { 19 int code = 0; 20 for(int f = 1; f <= 8; f++) { 21 for(int b = 1; b <= 8; b++) { 22 if(!G[f][b]) continue; 23 if(!G2[cor[f]][cor[b]]) return; 24 code |= 1 << map[cor[f]*10+cor[b]]; 25 } 26 } 27 set.add(code); 28 return; 29 } 30 for(int i = 1; i <= n; i++) { 31 if(opt[i]) continue; 32 opt[i] = true; 33 cor[d] = i; 34 dfs(d+1); 35 opt[i] = false; 36 } 37 } 38 39 void MAIN() { 40 while(cin.hasNext()) { 41 init(); 42 n = cin.nextInt(); 43 int m = cin.nextInt(); 44 int m2 = cin.nextInt(); 45 for(int f, b, i = 0; i < m; i++) { 46 f = cin.nextInt(); 47 b = cin.nextInt(); 48 G[f][b] = G[b][f] = true; 49 } 50 for(int f, b, i = 0; i < m2; i++) { 51 f = cin.nextInt(); 52 b = cin.nextInt(); 53 G2[f][b] = G2[b][f] = true; 54 map[f*10+b] = map[b*10+f] = i; 55 } 56 57 set.clear(); 58 dfs(1); 59 System.out.println(set.size()); 60 } 61 } 62 63 public static void main(String args[]) { new Main().MAIN(); } 64 }