AtCoder Beginner Contest 310 D

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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值