题目大意
给定一个图 (V,E),V≤26 ,节点表示广播站,现在让你给每个广播站分配一个频道(用一个数字表示),使得相邻的广播站的频道数不同。问最少用多少种频道能满足要求。
(重新描述一下题意):
信道分配。给定一个无向图,为每顶点填上颜色,要求满足相邻的顶点颜色不同,问最少的颜色数是多少?
分析
由于V比较小,考虑枚举,但直接枚举
2626
肯定超时,所以需要剪枝,把已经确定频道了的节点相邻的节点用一个数组来表示它不能在选择这个频道。
这种搜索写多了感觉套路都差不多了。
扩展
四色定理:
任何一个地图图都能用四种颜色来染色使得任意相邻的地区颜色都不同。
(代码中有个地方还没太搞懂)
代码
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<stack>
using namespace std;
const int INF=99999999;
int n;
int E[30][30];//E[i][j]表示节点i到j是否有边
int x[30][30];//x[i][j]表示节点i能否用channel j
int t[30];//t[i]表示第i个点的channel
int ans;
void In()
{
char s[50];
for(int i=1;i<=n;i++)
{
scanf("%s",s);
int a,b;
for(int i=0;i<strlen(s);i++)
{
b=(int)s[i]-(int)'A'+1;
if(i==0)a=b;
else if(i==1)continue;
else E[a][b]=1;
}
}
}
void Init()
{
ans=INF;
memset(E,0,sizeof(E));
memset(x,0,sizeof(x));
memset(t,0,sizeof(t));
}
void Update_ans()
{
int tempans=0;
for(int i=1;i<=n;i++) tempans=max(tempans,t[i]);
ans=min(ans,tempans);
}
void Update(int k,int a)
{
x[k][a]++;
for(int i=1;i<=n;i++)
if(E[k][i]==1)
x[i][a]++;
}
void re_Update(int k,int a)
{
x[k][a]--;
for(int i=1;i<=n;i++)
if(E[k][i]==1)
x[i][a]--;
}
void dfs(int k)
{
if(k==n+1)
{
Update_ans();
return ;
}
for(int i=1;i<=4;i++)
{
if(x[k][i]==0)
{
t[k]=i;
Update(k,i);
dfs(k+1);
re_Update(k,i);//神奇的是我去掉这句 还是AC,并且时间从16ms变为0
t[k]=0;
}
}
return ;
}
int main()
{
while(scanf("%d",&n)!=EOF && n!=0)
{
Init();
In();
dfs(1);
if(ans==1)printf("1 channel needed.\n");
else printf("%d channels needed.\n",ans);
}
return 0;
}