题目:
N个人围坐—圈,有M对朋友关系。
第i对朋友关系是指,编号是ai的人和编号是bi的人是朋友。
现在要给他们安排座位,要求所有相邻的人不能是朋友。
问共有多少种方案?
如果两个方案只有旋转角度不同,则我们将其视为─种方案。输入格式:
第一行包含两个整数N, M。
接下来M行,每行包含一对ai , bi。输出格式:
输出—个数,表示总方案数。
输入样例1:
4 1
1 2
输出样例1:2
输入样例2:
10 5
1 2
3 4
5 6
7 8
9 10
输出样例2:112512
解题思路:
使用dfs,首先思考结束递归的情况,当n个人搜索完毕要判断方案成不成立,需要判断最后安排的与第一安排的是否为朋友关系,如果不是朋友关系,此方案成立
普遍情况,枚举每一种可能从1到n个人进行排座位,判断条件为没排座且和上一人不是朋友,就将该人填入位置
package dfs;
import java.util.Scanner;
public class 圆桌座位 {
static int n, m;//个人 m对关系
static boolean[] st; //是否已经安排了座位 状态数组
static int[][] friend;//是否为朋友 1为朋友 0不是
static int[] a;//座位上安排的人
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
friend = new int[n + 1][n + 1];
st = new boolean[n + 1];
a = new int[n + 1];
for (int i = 0; i < m; i++) {
int a = sc.nextInt();
int b = sc.nextInt();
friend[a][b] = 1;
friend[b][a] = 1;// a和b是朋友关系
}
a[0] = 1;
st[1] = true;//定义开始
System.out.println(dfs(1));
}
public static int dfs(int step) {
if (step == n) {//出口 n个人搜索安排完毕
if (friend[a[step - 1]][a[0]] != 1) {// 检查最后一人与第一人的关系
return 1;
} else {
return 0;
}
}
int res = 0;
for (int j = 1; j <= n; j++) {// n个人进行排座位
if (!st[j] && friend[j][a[step - 1]] != 1) {// 当前人未排座位并且安排的人与上一人不是朋友
// 进行安排
a[step] = j;
st[j] = true;
res += dfs(step + 1);// 累加方案
st[j] = false;// 回溯
}
}
return res;
}
}