poj1129Channel Allocation 图的染色问题

#include <iostream>

#include <cstdio>

#include <string>

using namespace std;

#define X 305

string s;

int map[X][X],color[X],n,x,y,len,c,ans;

bool check(int a,int col) //检查顶点a的颜色能否涂成col

{

       for(int i=1;i<=n;i++)

              if(map[a][i]&&color[i]==col)      //相邻节点颜色与他一样,不行

                     return false;

       return true;

}

bool dfs(int tc,int v)      //搜索颜色总数为tc时,正在要涂色的是顶点v

{

       if(tc==n) //如果颜色总数等于n,因为之前的用较少的颜色都不能涂好,所以此处可直接返回真

              return true;

       if(v==n+1)     //如果把n个节点都涂完的话,直接返回真

              return true;

       for(int i=1;i<=tc;i++)    //从颜色1开始枚举,看看当前颜色是否能涂满所有顶点

       {

              color[v] = i;

              if(check(v,i))  //判断是否可以涂成颜色i

                     if(dfs(tc,v+1)) //如果下面的顶点同样能涂好,返回真

                            return true;

       }

       return false;

}

int solve()       //根据平面图的4色定理,枚举颜色1到4即可

{

       //////直接用1种颜色看看是否能涂好

       bool flag = true;

       for(int i=1;i<=n;i++)

              for(int j=i+1;j<=n;j++)

                     if(map[i][j])

                            flag = false;

       if(flag)

              return 1;

       for(int i=2;i<=4;i++)     //从2开始枚举

       {

              memset(color,0,sizeof(color));

              if(dfs(i,1))

                     return i;

       }

       return -1;

}

int main()

{

       freopen("sum.in","r",stdin);

       freopen("sum.out","w",stdout);

       while(cin>>n,n)

       {

              ans = 1;

              memset(map,0,sizeof(map));

              for(int i=0;i<n;i++)

              {

                     cin>>s;

                     len = s.size();

                     x = s[0] - 'A'+1;     //转化为图的邻接矩阵表示形式,切下标从1开始

                     for(int j=2;j<len;j++)

                     {

                            c = s[j]-'A'+1;

                            map[x][c] = map[c][x] = 1;

                     }

              }

              int ans = solve();

              if(ans==1)

                     printf("1 channel needed.\n");

              else

                     printf("%d channels needed.\n",ans);

       }

       return 0;

}

原文地址:https://www.cnblogs.com/yejinru/p/2407923.html