题目大意:给出一个无向图,问最少需要多少种颜色可以给这个图完全染色,要求相邻的两个点颜色不能一样
思路:数据小,直接暴力深搜了。
注意如果答案是一种颜色的话,输出的字符串里面channel单词后面木有s,表示不细心很坑爹啊有木有!!!
#include <iostream>
#include <cstring>
#include <cstdio>
#define maxn 30
using namespace std;
int g[maxn][maxn]; //邻接矩阵存储图
int n;
int color; //染色序号
int ic; //记录已经染色的点的数量
int col[maxn]; //每个点的颜色
bool init() //输入数据并建图
{
int len;
memset(g,0,sizeof(g));
memset(col,-1,sizeof(col));
color=0;
char s[maxn];
scanf("%d",&n);
for(int i=0; i<n; i++)
{
scanf("%s",s);
len=strlen(s);
for(int j=2; j<len; j++)
g[s[0]-'A'][s[j]-'A']=1;
}
return n;
}
bool check(int nd,int cl) //判断nd点能否被颜色cl颜色,如果可以返回true
{
for(int i=0; i<n; i++)
{
if(g[nd][i])
{
if(col[i]==cl)
return false;
}
}
return true;
}
bool dfs(int nd) //当前颜色的节点
{
int child=0;
if(ic>=n)return true; //颜色完毕,返回真
for(int j=0; j<color; j++)
{
if(check(nd,j))
{
col[nd]=j; //染之
ic++; //颜色的节点数量加一
child=0; //记录与这个店相邻的点的并且没有染色的数量,
for(int i=0; i<n; i++) //如果child等于0,说明和nd点相邻的点已经染色完毕了,可以返回true了
if(g[j][i]&&col[i]==-1)
{
child++;
if(dfs(i)) //深搜染色
return true;
}
if(child==0)
return true;
ic--;
}
}
col[nd]=color++;
ic++;
return false;
}
void slove()
{
ic=0;
for(int i=0; i<n; i++)
if(col[i]==-1)
dfs(i);
if(color!=1)
printf("%d channels needed.\n",color);
else
printf("%d channel needed.\n",color);
}
int main()
{
while(init())
slove();
return 0;
}