POJ1129—Channel Allocation

题目链接:http://poj.org/problem?id=1129

 

 

package D0808;

/*
 *题目大意:就是说相邻的两个点要隔离,要多少个那个什么东西(大概就这样)
 *思路:其实就是着色问题,有n个点,有变相连的点不能着同样的颜色,问你
 *最少需要几种颜色。 
 * 四色定理+dfs,
 * 
 * */
import java.util.*;

public class POJ1129 {
	static int[][] map;
	static boolean[] colored;
	static int n;

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while (sc.hasNext()) {
			n = sc.nextInt();
			if (n == 0)break;
			//初始化数组
			map = new int[n][n];
			colored = new boolean[n];
			//接收输入,给数组赋值
			for (int k = 0; k < n; k++) {
				String str = sc.next();
				
				int s = str.charAt(0) - 'A';
				for (int i = 2; i < str.length(); i++) {
					int e = str.charAt(i) - 'A';
					map[s][e] = 1;
				}
			}
			
			int cnum = dfs();
			if(cnum ==1)System.out.println("1 channel needed.");
			else System.out.println(cnum+" channels needed.");
		}

	}

	private static int dfs() {
		
		int color_num = 1;//颜色数目
		boolean no_side = true;//一条边都没有??
		
		//如果不存在边,只需要一种颜色即可
		for(int i = 0;i<n;i++)
			for(int j = i+1;j<n;j++)
				if(map[i][j]==1){
					no_side = false;
					break;
				}
		if(no_side)return color_num;
		
		//存在边----------四色定理
		for(color_num = 2;color_num<=4;color_num++){
			int[] x = new int[n];//保存每个顶点所着的颜色
			Arrays.fill(x, -1);
			if(solve(x,0,color_num,n))
				return color_num;
		}
		return -1;
	}
	
	/*
	 * @vnum:着色的顶点
	 * @color_num:颜色数目
	 * @n:顶点数目
	 * */
	private static boolean solve(int[] x, int vnum, int color_num, int n) {
		if(vnum==n)return true;//如果已经着色的顶点==顶点数目表示着色完成
		
		for(int i = 0;i<color_num;i++){// 如果某个顶点没有颜色填,返回上一层
			x[vnum] = i;
			if(check(x,vnum,i,n))
				if(solve(x,vnum+1,color_num,n))// 合法,枚举下一个顶点
					return true;
		}
		return false;
	}

	private static boolean check(int[] x, int vnum, int t, int n) {
		// TODO Auto-generated method stub
		boolean find = true;
		for (int i = 0; i < n && find; i++) {
			if (map[vnum][i] == 1 && x[i] == t)
				//如果顶点vnum和i之间有边,并且i已经着上了颜色t,那么vnum就不能着颜色t了。
				find = false;
		}
		return find;
	}

}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

怎么演

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值