首页 > 技术文章 > 蓝桥杯-分考场(dfs)

GarrettWale 2020-03-13 12:06 原文

分考场

PREV-53

  • 这题的解决方法使用dfs,因为数据很小,才100.
  • 每次当前的人人是否可以和前面的组队,设置两个数组group和fri
/*DFS求解:思路每次判断输入的人是否可以和前面的组队
问题描述
  n个人参加某项特殊考试。
  为了公平,要求任何两个认识的人不能分在同一个考场。
  求是少需要分几个考场才能满足条件。
输入格式
  第一行,一个整数n(1<n<100),表示参加考试的人数。
  第二行,一个整数m,表示接下来有m行数据
  以下m行每行的格式为:两个整数a,b,用空格分开 (1<=a,b<=n) 表示第a个人与第b个人认识。*/
package lanQiao;
import java.io.*;
import java.util.*;
public class T457 {
	static boolean [][]fri=new boolean[101][101];//是否是朋友
	static int [][]group=new int[101][101];//group[i][j]表示第i队第j个成员的编号
	static int ans=200;
	static int n,m;
	/**
	 * 
	 * @param p 表示第几个人
	 * @param kans 表示前面分成了几个队
	 */
	public static void dfs(int p,int kans) {
		if(kans>=ans)
			return;
		if(p==n+1) {//超出人数返回
			ans=Math.min(kans, ans);
			return;
		}
		for(int i=1;i<=kans;i++) {
			int k=0;
			while(group[i][k]>0&&!fri[p][group[i][k]])
				k++;
			if(group[i][k]==0) {//这里表示可以和第i对组成一队
				group[i][k]=p;
				dfs(p+1,kans);//队数不变
				group[i][k]=0;
			}
		}
		//判断完前面已经组的队伍后,再判断单独组队时,求解的和是否最少
		group[kans+1][0]=p;
		dfs(p+1,kans+1);
		group[kans+1][0]=0;
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(System.in));
		Scanner cin=new Scanner(System.in);
		n=cin.nextInt();m=cin.nextInt();
		for(int i=0;i<m;i++) {
			int a=cin.nextInt(),b=cin.nextInt();
			fri[a][b]=fri[b][a]=true;
		}
		dfs(1,0);
		System.out.println(ans);
	}
}

推荐阅读