POJ-1129-Channel Allocation-dfs搜索+四色定理

题目翻译:

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

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



就是给地图染色,,,,NP-hard问题..用贪心的方法是错误...但是poj的数据比较水,能混过去

贪心的会卡在这样的数据

in

6

A:BEF
B:AC
C:BD
D:CEF
E:ADF
F:ADE

out

3 channels needed.



即:A(1)B(2)C(3)D(1)E(2)F(3)



暴力dfs+四色定理剪枝



#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>  
#include <stack>
#include <iostream>
using namespace std;   
double eps=1e6; 
int mp[30][30]; 
int vis[30]; 
int n,ok;
int minn;
int cnt=1;
void work(int x)
{	 
	if (x>n)
	{
		int i;
		int cun[5];
		for (i=1;i<=n;i++)
			cun[vis[i]]=1;
		int ans=0;
		for (i=1;i<=ok;i++)
			ans+=cun[i];	//统计颜色种类
		if (ans<minn)
			minn=ans;
		return ;
	} 
	if (vis[x]) return ;
	int i;
	int use[5];	//根据四色定理,最多4种颜色足矣
	memset(use,0,sizeof(use)); 
	for (i=1;i<x;i++)
	{
		if (mp[x][i])
			use[vis[i]]=1;
		
	}
	for (i=1;i<=ok;i++)  //检查之前的颜色能不能重用
	{
		if (use[i]) continue;
		vis[x]=i;
		work(x+1);
		vis[x]=0;
	}
	if (ok==4) return ;		//四色定理剪枝
	
	vis[x]=++ok;		//用新颜色涂
	work(x+1);
	vis[x]=0;
	ok--;
	
}

int main()
{
	int st,i,j,k;
	int t; 
	while(1)
	{
		ok=0;
		memset(mp,0,sizeof(mp));
		char tmp[105]; 
		cin>>n;
		if (!n)break;
		for (i=1;i<=n;i++)
		{ 
			scanf("%s",tmp);
			int len=strlen(tmp); 
			int x=tmp[0]-'A'+1;
			for (j=2;j<len;j++)
			{
				int v=tmp[j]-'A'+1;
				mp[x][v]=1;
			} 
		}
		minn=999l;
		memset(vis,0,sizeof(vis));
		work(1); 
		if (minn==1)
			printf("1 channel needed.\n");
		else
			printf("%d channels needed.\n",minn);
	}
	
	return 0;
}


你可能感兴趣的:(POJ-1129-Channel Allocation-dfs搜索+四色定理)