D - Peaceful Teams (atcoder.jp)
思路:因为数据范围很小,采取爆搜的方法去解决,如何优雅的爆搜,对于每个人,我们将其编号为1-n,将其分配到t个队伍中,枚举每个人处于t1,t2,t3……等情况,当所有人都分配完毕且队伍数合法的时候,对仇敌进行检查,若两个仇敌处于同一队,则不合法,否则方案数++。
#include<bits/stdc++.h>
using namespace std;
const int N=5e5+5;
typedef long long ll;
typedef pair<ll,ll> pll;
int mod=1e9+7;
const int maxv=4e6+5;
int n,t,m;
int res;
int a[N],b[N];
int z[N];//记录每一个人所在的队伍
void dfs(int c,int val)//c记录的是队伍数,val记录的是当前人的编号
{
if(val==n+1){//因为是从1开始,所以需要到n+1结束
if(c!=t+1) return ;//判断队伍总数是否合法
int f=1;
for(int i=1;i<=m;i++){
if(z[a[i]]==z[b[i]]){//如果仇敌在同一个队伍则不合法
f=0;
break;
}
}
res+=f;
return ;
}
for(int i=1;i<=c;i++){//枚举当前这个人在第几个队伍
z[val]=i;
dfs(max(i+1,c),val+1);//max(i+1,c)的含义为,当前的队伍数。因为当前这个人也可能单独开一个新的队伍,i+1则保证了当i=c时,这个人会进入一个新的队伍
}
}
void solve()
{
cin>>n>>t>>m;
for(int i=1;i<=m;i++){
cin>>a[i]>>b[i];
}
dfs(1,1);
cout<<res<<endl;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
t=1;
//cin>>t;
while(t--){
solve();
}
system("pause");
return 0;
}