pku 1129 Channel Allocation dfs 涂色问题

//题目分析:用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(递归)其实是一个抽象的过程,它里面有很多子过程,而且还有一些重复的叠加在一起的操作,用的时候,我们即需要有整体的把握,也需要对内部细节的分析

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值