//题目分析:用dfs搜索 ,dfs(int index,int color) //index搜索到的下标,color是颜色的种数
#include<iostream>
#include<string>
using namespace std;
int mat[30][30];
int mark[30];
int n;
bool dfs(int index,int color)
{ int i,j;
bool flag;
for(i=0;i<color;i++)
{ flag=true;
mark[index]=i;
for(j=0;j<index;j++)
{ if(mat[index][j]&&mark[index]==mark[j])
{ flag=false;
break;
}
}
//该颜色有效哦,那么就可以搜索下一个节点
if(flag&&(index==n-1||dfs(index+1,color)))
return true;
}
return false;
}
int main()
{
int i,j,ans,one;
string s;
while(scanf("%d\n",&n)!=EOF&&n) //这里的读入要这样写,可以把回车符给去掉
{ one=1;
memset(mat,0,sizeof(mat));
memset(mark,0,sizeof(mark));
for(i=0;i<n;i++)
{ //getline(cin,s);
cin>>s;
for(j=2;j<s.length();j++)
{ mat[s[0]-'A'][s[j]-'A']=1;
mat[s[j]-'A'][s[0]-'A']=1;
one=0;
}
}
if(one)
{ printf("1 channel needed.\n");
}
else if(dfs(0,2))
{ printf("2 channels needed.\n");
}
else if(dfs(0,3))
{ printf("3 channels needed.\n");
}
else
{ printf("4 channels needed.\n");
}
}
return 0;
}
//dfs的一般思路都是要有一个搜索节点的下标,用来记录搜索的位置,然后这题由于是涂色问题,经过分析可以知道最多需要4种颜色就可以了,那么我们只要依次枚举这4种颜色的情况就可以了,看这样涂的时候,会不会产生冲突。。。
//本题要处理的关键
1:是建图,一般图论的题目都是要有这么一步的,而建图,有两种存储图的方式,邻接表和邻接矩阵,这里采用了邻接矩阵的形式,邻接矩阵记录的是相邻的两个节点的信息,而且这里由于图是对称的,因此建图的时候会有两句话。
2:建好图之后,就是用dfs判断的过程,如果所有的都不相邻,那么很明显的就是只要一种颜色就可以了。否则的话,用dfs来判断
3:dfs的流程就是对于当前枚举到的节点,我们要给它一种颜色(颜色的选择需要遍历,因此有了第一层用来控制颜色的循环),然后我们就需要判断这样的涂色是否会产生冲突,我们就再遍历一下该节点以前的节点,也即那些已经涂好色的点,只要满足相邻的节点有不同的颜色就行了,否则的话,说明这种涂色方法不对,需要换一种颜色来涂,这里用了一个break,使得循环调到第一层去,换色。。如果满足涂色的条件,那么我们就可以递归的去涂下一个节点,就这样一直涂到结束,结束条件是index==n-1
dfs(递归)其实是一个抽象的过程,它里面有很多子过程,而且还有一些重复的叠加在一起的操作,用的时候,我们即需要有整体的把握,也需要对内部细节的分析