客服管理员管理着n个客服小姐,他需要为每一组安排客服24小时值班,为简单起见,假设每组只有两个客服,一天只需要1个客服上班,并且一些客服由于某些原因不能在同一天上班,我们已经对客服进行了编号,第i(i>=1&&i<=n) 个组的客服编号为2*i-1和2*i,并且知道了m种如下约束关系:客服编号a和编号b不能一起上班,管理员选哟你帮忙判断一下今天是否存在可行的方案,既满足m条约束,又能让每组有一个客服上班。
输入:n(代表有n个组)
m:m条约束,接下来会有m行数据
a,b(代表a b两位客服标号不能同时上班)
输出:判断是否可行,如果不行输出no,可行输出yes
举例:
输入:
4
3
1,4
2,3
7,3
输出:yes
解释:这可以用深度优先搜索来解决问题,但是需要维护一个容器来存储已经选择的客服编号用于约束条件的判断,每存入一个新的客服编号,就判断一次约束是否成立,如果成立,递归进入下一组,不成立则删除刚存入的编号,返回上一层
import java.util.ArrayList;
import java.util.Scanner;
public class Test{
public static void main(String[] args) {
Scanner sca = new Scanner(System.in);
//组数、约束条件数、约束条件
int zu=sca.nextInt();
int limit=sca.nextInt();
int[][] map=new int[limit][2];
for(int i=0;i<limit;i++) {
for (int j=0;j<2;j++) {
map[i][j]=sca.nextInt();
}
}
boolean flag=fun(zu,map);
System.out.println(flag);
}
static boolean fun(int zu,int[][] map ) {
//创建一个数组列表,存储已经选择的编号
ArrayList<Integer> al = new ArrayList<Integer>();
//第一组,先存入编号1,进入递归函数
if(fun1(0,zu,1,al,map)) {
return true;
}
al.remove(0);
if(fun1(0,zu,2,al,map)) {
return true;
}
return false;
}
//fun1(当前层数,总层数,要加入的客服编号,数组列表,约束条件阵列)
static boolean fun1 (int index,int zu,int rl,ArrayList<Integer> al,int[][] map) {
boolean flag=false;
if(index==zu) { //代表最后一层已经加进去了,可以满足排班
return true;
}
else {
/*
* 将当前层的一个编号加入,然后判断是否满足约束条件,满足则进入下一层递归调用,分别加入
* 下一层层第一个编号和第二个编号,不满足则删除最后加入的编号,返回上一层
*/
al.add(index*2+rl);
if(fun2(al,map)) {
if(fun1(index+1,zu,1,al,map)) {
return true;
}
if(fun1(index+1,zu,2,al,map)) {
return true;
}
}
else {
al.remove(al.size()-1);
return false;
}
}
return flag;
}
//传入数组列表和约束条件阵列,若符合条件,返回true
static boolean fun2(ArrayList<Integer> al,int[][] map) {
boolean flag=true;
for (int i=0;i<map.length;i++) {
if(al.contains(map[i][0])&al.contains(map[i][1])) {
flag=false;
break;
}
}
return flag;
}
}