POJ 1129-Channel Allocation 的贪心算法解法(图的m着色问题)

题目翻译:

当一个广播电台在一个非常大的地区,广播站会用中继器来转播信号以使得每一个接收器都能接收到一个强烈的信号。然而,每个中继器必须慎重选择使用,使相邻的中继器不互相干扰。如果相邻的中继器使用不同的频道,那么就不会相互干扰。

由于无线电频道是一有限的,一个给定的网络所需的中继频道数目应减至最低。编写一个程序,读取一个中继网络,然后求出需要的最低的不同频道数。

建模:

一个有N个节点的无向图,要求对每个节点进行染色,使得相邻两个节点颜色都不同,问最少需要多少种颜色?

那么题目就变成了一个经典的图的染色问题。

这题数据范围很小(节点最多26个),由四色定理可以得知最多需要4种颜色.

输入输出格式如下:(第一行是顶点数n,接下来n行表示每一个顶点与其它顶点的连接情况,当n=0时结束。对每一种情况输出对应的最小颜色数)
Sample Input

2
A:
B:
4
A:BC
B:ACD
C:ABD
D:BC
4
A:BCD
B:ACD
C:ABD
D:ABC
0Sample Output

1 channel needed.
3 channels needed.
4 channels needed.

贪心算法[url]http://128kj.iteye.com/blog/1684981[/url]。“贪心”算法的思想是首先 用第一种颜色对图中尽可能多的顶点着色(“尽可能多”表现出“贪心”);然后用第二种颜色对余下的顶点中尽可能多的顶点着色;如此等等,直到把所有的顶点都着完色。当用一种新颜色对余下的顶点着色时,我们采取下列步骤:

(1)选取某个未着色的顶点,并且用新颜色对它着色。

(2)扫描所有未着色的顶点集,对其中的每个顶点,确定它是否与已着新颜色的任何顶点相邻。若不相邻,则用新颜色对它着色。

import java.util.Scanner;
import java.util.Arrays;

public class Main{

int n;//顶点数
int[] color;//color[k]=m表示第k个顶点着色m
int[][] c;//邻接矩阵

public Main(int n,int[][]c){
this.n=n;
this.c=c;
color=new int[n+1];
}

private boolean ok(int k,int r)//判断顶点k的着色是否发生冲突
{

for(int i=1;i<n;i++){
if(color[i]!=r) continue;
if(c[k][i]==1&&color[i]==r )
return true;
}
return false;
}

private int graphcolor()
{
for(int i=1;i<=n;i++)
color[i]=0;//初始化
int k=1,m=0,sum=0;
while(sum<n){
m++;
for(int i=1;i<=n;i++){
if(color[i]==0){
k=i;
color[k]=m;
sum++;
break;
}
}

for(int i=k+1;i<=n;i++){
if(color[i]!=0) continue;
if (ok(i,m)) continue;
else {
color[i]=m;
sum++;

}
}

}

return m;
}
public static void main(String rgs[]) throws Exception
{
Scanner cin = new Scanner(System.in);
int n=cin.nextInt();


while(n!=0){
int[][] g=new int[n+1][n+1];
for(int i=0;i<=n;i++)
Arrays.fill(g[i],0);
for(int i=1;i<=n;i++){
String s = cin.next();
for(int j=2;j< s.length();j++)
g[i][s.charAt(j)-'A'+1]=1;

}
Main gc=new Main(n,g);
int count=gc.graphcolor();
if(count==1)
System.out.println(count+" channel needed.");
else
System.out.println(count+" channels needed.");
n=cin.nextInt();
}
}


}

下载源码:
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值