ACWing 1491. 圆桌座位(dfs)

1491. 圆桌座位 - AcWing题库

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

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

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

问共有多少种方案?

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

输入格式

第一行包含两个整数 N,M𝑁,𝑀。

接下来 M𝑀 行,每行包含一对 ai,bi𝑎𝑖,𝑏𝑖。

输出格式

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

数据范围

3≤N≤103≤𝑁≤10,
0≤M≤N(N−1)20≤𝑀≤𝑁(𝑁−1)2,
1≤ai<bi≤N1≤𝑎𝑖<𝑏𝑖≤𝑁,
(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
/*
要求所有相邻的人不能是朋友的排位为情况有几种。
先固定一个1,然后枚举安排剩下的人,当枚举完后,再检查最后一个人与第一个人是不是朋友

*/

#include<iostream>

using namespace std;

const int N = 15,M = 50;

bool g[N][N],st[N]; //g[i][j] i 和 j是朋友的话为true,st[i] 检查当前的人有么有用给过
int pos[N]; //记录每个人的位置
int n,m;

int dfs(int u)
{
    if(u - 1 == n)  //当所有人枚举完后,检查最后一个人与第一个人是不是朋友
    {
        if(g[pos[n]][pos[1]])
            return 0;
        return 1;
    }
    
    int res = 0;
    
    for(int i = 2;i<=n;i++) 
    {
        if(!st[i] && !g[i][pos[u - 1]])     //当前人没有用过,并且与前一个人不是朋友,那么第u个位置为i
        {
            pos[u] = i;
            st[i] = true;       //标记用过
            res += dfs(u + 1);
            st[i] = false;  //还原现场
        }
    }
    
    return res;
}

int main()
{
   
    cin >>n >>m;
    
    while( m --)
    {
        int a,b;
        cin >>a>>b;
       g[a][b] = g[b][a] = true;        //i和j j和i是一样的
    }
    
    pos[1] = 1;
    st[1] = true;   //第一个人先固定
    
    cout <<dfs(2);  //从第二个人开始进行枚举
    return 0;
}

ps:dfs搜索的是第i给位置上是谁,也就是所在枚举所有人的时候要保证当前的人没有被用过并且与前一位已经安排好的人不是朋友,这样才能坐到相邻


挑战模式

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
循环队列可以用来实现圆桌会议的座位安排。以下是一个简单的示例代码: ```python class CircularQueue: def __init__(self, capacity): self.capacity = capacity self.queue = [None] * capacity self.head = 0 self.tail = 0 def enqueue(self, item): if (self.tail + 1) % self.capacity == self.head: raise Exception("Queue is full") self.queue[self.tail] = item self.tail = (self.tail + 1) % self.capacity def dequeue(self): if self.head == self.tail: raise Exception("Queue is empty") item = self.queue[self.head] self.queue[self.head] = None self.head = (self.head + 1) % self.capacity return item def __len__(self): if self.tail >= self.head: return self.tail - self.head else: return self.capacity - self.head + self.tail def assign_seats(num_people, num_seats): queue = CircularQueue(num_seats) for i in range(1, num_people+1): queue.enqueue(i) while len(queue) > 1: for i in range(num_seats-1): queue.enqueue(queue.dequeue()) print("Person", queue.dequeue(), "leaves the table") print("Person", queue.dequeue(), "gets the last seat and wins the game") ``` 上述代码定义了一个名为 `CircularQueue` 的循环队列类,其中包括了 `enqueue` 和 `dequeue` 两个基本操作。`assign_seats` 函数用于实现座位的安排,其中 `num_people` 表示总人数,`num_seats` 表示座位数。在循环中,每个人依次入队,然后循环执行一定次数的出队操作,模拟人们依次离开座位,最后剩下一个人获得最后一个座位

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值