dfs优化剪枝

发布时间 2023-07-19 10:29:43作者: zouyua

题目链接:D - Peaceful Teams (atcoder.jp)

先看数据范围,肯定是搜索相关

首先想到从第1个人, 第0个队开始的搜索顺序 ,因为这属于内部顺序,所以每次搜索要回溯状态,注意要进行大量剪枝

#include<bits/stdc++.h>

using namespace std;
using ull = unsigned long long;
using ll = long long;
using PII = pair<int,int>;
#define endl "\n"
#define pb push_back
const int N=1e3+10;
const int INF=0x3f3f3f3f;
int a[N], b[N];
int team[N];
int res;
int n, t, m;
void dfs(int u, int tn)
{
    if(u > n)
    {
        if(tn != t) return ;
        
        for(int i = 1; i <= m; i ++)
        {
            if(team[a[i]] == team[b[i]]) return ;//判断是否人所在的队不合法,可行性剪枝
        }
        res ++;
        return ;
    }
    if(n - (u - 1) < t - tn) return ;//因为搜索的是u+1 个人,所以u-1,判断最低剩下的队有人在是否
    
    for(int i = 1; i <= tn; i ++)
    {
        team[u] = i;//先把当前人员装到上个人的队中
        dfs(u + 1, tn);//递归搜索下个人
        team[u] = 0;//回溯状态
    }
    if(tn + 1 <= t)
    {
        team[u] = tn + 1;//新开一队
        dfs(u + 1, tn + 1);//搜索下个人
        team[u] = 0;
    }
}
int main()
{
    cin >> n >> t >> m;
    for(int i = 1; i <= m; i ++) cin >> a[i] >> b[i];
    dfs(1, 0);//从第一个人开始,当前队有0个对
    cout << res << endl;
    
    return 0;
}

相似题目:1118. 分成互质组 - AcWing题库 165. 小猫爬山 - AcWing题库