1491. 圆桌座位(DFS)

N 个人围坐一圈,有 M 对朋友关系。

第 i 对朋友关系是指,编号是 ai的人和编号是 bi 的人是朋友。

现在要给他们安排座位,要求所有相邻的人不能是朋友。

问共有多少种方案?

如果两个方案只有旋转角度不同,则我们将其视为一种方案。

输入格式
第一行包含两个整数 N,M。

接下来 M 行,每行包含一对 ai,bi

输出格式
输出一个数,表示总方案数。

数据范围
3≤N≤10,
0≤M≤ N ( N − 1 ) 2 \frac{N(N−1) }{2} 2N(N1),
1≤aii≤N,
(ai,bi)≠(aj,bj),
所有输入均为整数。

输入样例1:

4 1
1 2

输出样例1:

2

输入样例2:

10 5
1 2
3 4
5 6
7 8
9 10

输出样例2:

112512

代码

#include 
using namespace std;
int n,m;
int path[15];//安排的方案
bool r[15][15],vis[15];//r为朋友关系、vis代表第i个人是否已经被使用
int dfs(int x){
    if(x==n){//当安排好n个人后
        //注意:是path[0]则不是0
        if(r[path[n-1]][path[0]])//如果第0个位置和最后一个位置(环的首尾位置)是朋友关系
            return 0;//不是方案之一
        return 1;//方案加一
    }
    int result=0;
    for(int i=1;i<=n;i++){//遍历所有的人
        //如果该人未被使用并且当前预安排的人与上一个安排的人不是朋友关系
        if(!vis[i] && !r[i][path[x-1]]){//注意:path[x-1]代表上一个安排的人
            vis[i]=true;//标记该人已被使用
            path[x]=i;//第x个位置安排第i个人
            result+=dfs(x+1);//安排第x+1个位置
            vis[i]=false;//回溯
        }
    }
    return result;
}
int main()
{
    cin>>n>>m;//数据规模只有10这么小的题很大可能就是爆搜
    for(int i=1;i<=m;i++){
        int a,b;
        cin>>a>>b;
        r[a][b]=true;//两人是朋友关系
        r[b][a]=true;
    }
    //设置第一个人已被使用
    vis[1]=true;
    //因为旋转不同,视为同一种方案,所以固定住第一个人永远为1
    //那些不是以1开头的排列其实都可以由1开头的排列旋转得到
    path[0]=1;
    //注意:因为第0个位置已经固定好安排序号为1的人了,所以dfs要从1开始
    cout<<dfs(1)<<endl;
    return 0;
}

你可能感兴趣的:(算法笔试面试常考题,c++,算法)