Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 9898 | Accepted: 5059 |
Description
Input
Output
Sample Input
2 A: B: 4 A:BC B:ACD C:ABD D:BC 4 A:BCD B:ACD C:ABD D:ABC 0
Sample Output
1 channel needed. 3 channels needed. 4 channels needed.
Source
解题思路:
对于这题数据范围很小(节点最多26个),所以使用普通的暴力搜索法即可
对点i的染色操作:从最小的颜色开始搜索,当i的直接相邻(直接后继)结点已经染过该种颜色时,搜索下一种颜色。
就是说i的染色,当且仅当i的临近结点都没有染过该种颜色,且该种颜色要尽可能小。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct node
{
int next[54];
int pn;
};
int main( )
{
int n;
int i,j;
char s[54];
while(scanf("%d",&n)!=EOF)
{
if(n==0) break;
node point[n+n];
int len;
for( i=1;i<=n;i++)
point[i].pn=0;
for( i=1;i<=n;i++)
{
scanf("%s",s);len=strlen(s);
for( j=2;j<len;j++)
{
int k=s[j]%('A'-1);////把结点字母转换为相应的数字,如A->1 C->3
point[i].next[++point[i].pn]=k;
}
}
int color[54]={0};////color[i]为第i个结点当前染的颜色,0为无色(无染色)
color[1]=1;//结点A初始化染第1种色
int maxcolor=1; //当前已使用不同颜色的种数
for( i=1;i<=n;i++)//枚举每个顶点
{
color[i]=n+1;//先假设结点i染最大的颜色
int vis[54]={0};//标记第i种颜色是否在当前结点的相邻结点染过
for( j=1;j<=point[i].pn;j++)//枚举顶点i的所有后继
{
int k=point[i].next[j];
if(color[k])//顶点i的第j个直接后继已染色
{
vis[color[k]]=1;//标记该种颜色
}
}
for( j=1;;j++)//从最小的颜色开始,枚举每种颜色,最终确定结点i的染色
{
if(!vis[j]&&color[i]>j)
{
color[i]=j;
break;
}
}
if(maxcolor<color[i]) maxcolor=color[i];
}
printf("%d ",maxcolor);
if(maxcolor==1) puts("channel needed.");
else puts("channels needed.");
}
return 0;
}
链接:http://poj.org/problem?id=1129