poj1129

11 篇文章 0 订阅

典型的图着色问题。相邻的顶点不能着相同颜色,贪心算法,O(n^n)复杂度,大致说一下思路:

即初始化每个顶点的颜色为0(表示无颜色),然后贪心算法给每个顶点涂色,涂色时初始化每个顶点颜色编号为1,然后枚举其相邻的顶点是否由于其相同的颜色,若存在则增加其颜色,按照这样的策略,则能保证最后会用最少的颜色数量。

下面是代码: 172K+0MS

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#define Max 30
using namespace std;
bool trim[Max][Max];
int set[Max];
int n;
void set_color(int index){
	int *temp=new int[n+1],pivot=0;
    for(int i=1;i<=n;i++)
		if(trim[index][i])
			temp[pivot++]=set[i];
	sort(temp,temp+pivot);
	set[index]=1;
	for(int i=0;i<pivot;i++)
		if(set[index]==temp[i])
			set[index]++;
    delete temp;
}
int main(){
	while(scanf("%d",&n),n){
		getchar();
		memset(trim,0,sizeof(trim));
		memset(set,0,sizeof(set));
		for(int i=1;i<=n;i++){
			getchar();
			getchar();
			char temp=getchar();
			while(temp!='\n'){
				trim[i][temp-'A'+1]=true;
				temp=getchar();
			}
		}
		for(int i=1;i<=n;i++)
			set_color(i);
		int Sum=1;
		sort(set+1,set+1+n);
		for(int i=2;i<=n;i++)
			if(set[i]!=set[i-1])
				Sum++;
	    if(Sum==1)
			printf("1 channel needed.\n");
		else
			printf("%d channels needed.\n",Sum);
	}
	return 0;
}


下面是dfs模拟贪心算法代码:

代码如下: 172K+0MS

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#define Max 30
using namespace std;
bool trim[Max][Max];
int set[Max];
int n;
int dfs(int index){
	if(index==n+1){
		sort(set+1,set+1+n);
		int Sum=1;
		for(int i=2;i<=n;i++)
			if(set[i]!=set[i-1])
				Sum++;
		return Sum;
	}
	int *temp=new int[n],pivot=0;
	for(int i=1;i<=n;i++)
		if(trim[index][i])
			temp[pivot++]=set[i];
	sort(temp,temp+pivot);
	set[index]=1;
	for(int i=0;i<pivot;i++)
		if(set[index]==temp[i])
			set[index]++;
	delete temp;
	return dfs(index+1);
}

int main(){
	while(scanf("%d",&n),n){
		getchar();
		memset(trim,0,sizeof(trim));
		memset(set,0,sizeof(set));
		for(int i=1;i<=n;i++){
			getchar();
			getchar();
			char temp=getchar();
			while(temp!='\n'){
				trim[i][temp-'A'+1]=true;
				temp=getchar();
			}
		}
		int result=dfs(1);
	    if(result==1)
			printf("1 channel needed.\n");
		else
			printf("%d channels needed.\n",result);
	}
	return 0;
}
	


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值