【转】POJ1129-Channel Allocation:DFS 四色定理 剪枝枚举

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
bool g[26][26];
int used[26];
int n;

//id 是当下着色结点 color是限制的颜色数量
bool dfs(int id, int color)
{
        bool flag;// 标记 节点id 染第i种色成功与否
        for(int i=0; i<color; i++)
        {
                flag=true;
                used[id]=i;// 当前节点id涂第i种颜色
                for(int j=0; j<id; j++)// 判断id的已涂过色的邻接点是否使用了第i种颜色
                    if(g[id][j]&&used[id]==used[j])
                    {
                            flag=false;// 该i颜色已经使用过了
                            break;// 跳出转而进行第i+1颜色的尝试
                    }
                if( flag && ( id==n-1 || dfs(id+1, color) ) )// 搜索终点是 全部节点都已涂色成功 从而不必再dfs了
                    return true;
        }
        return false;// 节点id进行color个颜色的尝试 未能成功着色 也就是说color个颜色都用过了 id节点无色可染
}

int main()
{
        char adjacent[50];
        while(scanf("%d", &n)&&n)
        {
                    memset(g, 0, sizeof(g));
                    memset(used, 0, sizeof(used));
                    bool one = true;
                    for(int i=0; i<n; i++)
                    {
                            scanf("%s", adjacent);
                            for(int j=2; adjacent[j]!='\0'; j++, one=false)
                            {
                                    g[i][adjacent[j]-'A']=true;
                                    g[adjacent[j]-'A'][i]=true;
                            }
                    }
                    // 根据四色定理 可知颜色不超过四种 则逐一枚举 可行性剪枝
                    if(one)
                        printf("1 channel needed.\n");
                    else
                        if(dfs(1,2))
                            printf("2 channecls needed.\n");
                    else
                        if(dfs(1,3))
                            printf("3 channels needed.\n");
                    else
                        printf("4 channels needed.\n");
        }
        return 0;
}

  

posted @ 2015-08-13 19:14  _SunDaSheng  阅读(177)  评论(0编辑  收藏  举报