5-27 部落卫队问题
问题描述
原始部落 byteland 中的居民们为了争夺有限的资源,经常发生冲突。几乎每个居民都有他的仇敌。部落酋长为了组织一支保卫部落的队伍,希望从部落的居民中选出最多的居民入 伍,并保证队伍中任何 2 个人都不是仇敌。
给定 byteland 部落中居民间的仇敌关系,编程计算组成部落卫队的最佳方案。
数据输入:
第 1 行有 2 个正整数 n 和 m,表示 byteland 部落中有 n个居民,居民间有 m 个仇敌关系。居民编号为 1,2,…,n。接下来的 m 行中,每行有 2 个正整数 u 和 v,表示居民 u 与居民 v 是仇敌。
Java
package Chapter5HuiSuFa;
import java.util.Scanner;
public class BuLuoWeiDui {
private static int n,m;
private static boolean[][] enemy;
private static int[] x,bestx;
private static int cn,bestn;
public static void main(String[] args){
Scanner input = new Scanner(System.in);
while (true){
cn = 0;
bestn = 0;
n = input.nextInt();
m = input.nextInt();
enemy = new boolean[n+1][n+1];
x = new int[n+1];
bestx = new int[n+1];
for(int i=1; i<=m; i++){
int a = input.nextInt();
int b = input.nextInt();
enemy[a][b] = true;
enemy[b][a] = true;
}
for(int i=0; i<=n; i++)
x[i] = 0;
backtrack(1);
System.out.println(bestn);
for(int i=1; i<=n; i++)
System.out.print(bestx[i]+" ");
}
}
private static void backtrack(int i){
if(i > n){
for(int j=1; j<=n; j++)
bestx[j] = x[j];
bestn = cn;
return;
}
boolean ok = true;
for(int j=1; j<i; j++)
if(x[j]>0 && enemy[i][j]){
ok = false;
break;
}
if(ok){
x[i]=1; cn++;
backtrack(i+1);
x[i]=0; cn--;
}
if(cn+n-i > bestn){
x[i] = 0;
backtrack(i+1);
}
}
}
Input & Output
7 10
1 2
1 4
2 4
2 3
2 5
2 6
3 5
3 6
4 5
5 6
3
1 0 1 0 0 0 1
7 10
1 2
1 3
1 6
1 7
2 3
3 4
3 5
4 5
5 6
5 7
4
0 1 0 1 0 1 1
Reference
王晓东《计算机算法设计与分析》(第3版)P187

部落卫队问题是一个经典约束优化问题,目标是从居民中选择最多的人组成卫队,条件是任何两人间不能有仇敌关系。给定居民间的仇敌关系,通过回溯法可以找到最佳解决方案。数据输入包括居民数量和仇敌关系,Java实现是问题求解的一种方式。
1万+

被折叠的 条评论
为什么被折叠?



