题意:
给定一个图。如今要给每个点分配一个频段(可视为染上一种颜色)。要求如果某两个点之间有边,则染上的颜色不能相同。为如何颜色可以使使用的颜色数最少。
思路:
因为数据量N<=26,所以颜色种类数最多为26。
从1到n依次染色,初始时染色点1为颜色1,即color[1]=1;
对于每个点,他的颜色可能值用一个has数组表示。
如果它与已经染色的点之间有边,则将该has值赋值true。
然后遍历该has数组,找出最小的i使得has[i]==false,即可能使用的颜色。然后color[now]=i;
然后再进行下一个点。直到n点都染色完毕。
这样时间复杂度O(26*26).
一次AC.记得之前写图论题的时候,曾经被染色的问题整的半死,一看到染色就有畏惧感。
现在想想其实是基础不扎实就接触图论的比较复杂的染色建图之类的题目,下场必须惨。
#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<cmath>
#include<algorithm>
#define llong long long
#define Min(a,b) (a<b?a:b)
#define Max(a,b) (a>b?a:b)
#define Abs(a) ((a)>0?(a):-(a))
#define Mod(a,b) (((a)-1+(b))%(b)+1)
using namespace std;
int n,m;
const int N=30;
const int inf=99999999;
bool mat[N][N];
int color[N];
void solve()
{
memset(color,0,sizeof(color));
color[1]=1;
for(int i=1;i<=n;i++)
{
bool has[N]={0};
for(int j=1;j<i;j++)
{
if(mat[j][i])
has[color[j]]=true;
}
int k=1;
while(has[k])
{
k++;
}
color[i]=k;
}
int ans=0;
for(int i=1;i<=n;i++)
ans=Max(ans,color[i]);
if(ans>1)
printf("%d channels needed.\n",ans);
else
printf("%d channel needed.\n",ans);
}
int main()
{
while(scanf("%d",&n),n)
{
char str[30];
memset(mat,0,sizeof(mat));
for(int i=1;i<=n;i++)
{
scanf("%s",str);
for(int j=2;j<strlen(str);j++)
{
mat[i][str[j]-'A'+1]=true;
mat[str[j]-'A'+1][i]=true;
}
}
solve();
}
return 0;
}