题目大意建模:

一个有N个节点的无向图,要求对每个节点进行染色,使得相邻两个节点颜色都不同,问最少需要多少种颜色?

那么题目就变成了一个经典的图的染色问题

例如:N=7

A:BCDEFG

B:ACDEFG

C:ABD

D:ABCE

E:ABDF

F:ABEG

G:ABF

画成图就是:

首先考虑四色定理:任何一张地图只用四种颜色就能使具有共同边界的国家着上不同的颜色

judge(int x,int y)枚举判断x的邻接点中是否着色y颜色的

1.正向考虑dfs(int num,int color)从第一个点开始从前往后用color种颜色给num个点着色

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
char ch[];
bool vis[];
int n,col[],graph[][];
bool judge(int x,int y)
{//判断在x点是否可以着色y
for(int i=;i<n;i++){
if(graph[x][i])
if(col[i]==y) return false;
}
return true;
}
bool dfs(int num,int color)
{
if(num>n)
return true;
for(int i=;i<num;i++){//dfs()函数含义体现在此处for循环
if(!vis[i]){
vis[i]=true;
for(int j=;j<=color;j++){
if(judge(i,j)){
col[i]=j;//着色
if(dfs(num+,color))
return true;
}
}
vis[i]=false;
}
}
return false;
}
int main()
{
while(scanf("%d",&n),n){
memset(graph,,sizeof(graph));
for(int i=;i<n;i++){
cin>>ch;for(int j=;j<strlen(ch);j++)
graph[ch[]-'A'][ch[j]-'A']=;
}
for(int i=;i<=;i++){
memset(vis,,sizeof(vis));
if(dfs(,i)){
if(i==)
printf("1 channel needed.\n");
else
printf("%d channels needed.\n",i);
break;
}
}
}
}

2.反向考虑dfs(int num,int color)从第n个点开始从后往前用color种颜色给剩下的num个点着色,同时减少vis[30]数组的开辟

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
char ch[];
int n,col[],graph[][];
bool judge(int x,int y)
{
for(int i=;i<n;i++){
if(graph[x][i])
if(col[i]==y) return false;
}
return true;
}
bool dfs(int num,int color)
{
if(!num)
return true;//dfs()函数含义体现在此处for循环
for(int i=num-;i>=;i--){//或者for(int i=0;i<num;i++)
if(!col[i]){
for(int j=;j<=color;j++){
if(judge(i,j)){
col[i]=j;
if(dfs(num-,color))
return true;
}
}
col[i]=;
}
}
return false;
}
int main()
{
while(scanf("%d",&n),n){
memset(graph,,sizeof(graph));
for(int i=;i<n;i++){
cin>>ch;for(int j=;j<strlen(ch);j++)
graph[ch[]-'A'][ch[j]-'A']=;
}
for(int i=;i<=;i++){
memset(col,,sizeof(col));
if(dfs(n,i)){
if(i==)
printf("1 channel needed.\n");
else
printf("%d channels needed.\n",i);
break;
}
}
}
}

3.dfs(int num,int color)从第num个点开始用color种颜色着色,函数含义体现在自身

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
char ch[];
bool vis[];
int n,col[],graph[][];
bool judge(int x,int y)
{
for(int i=;i<n;i++){
if(graph[x][i])
if(col[i]==y) return false;
}
return true;
}
bool dfs(int num,int color)
{
if(num>n)
return true;
for(int i=num-;i<n;i++){//和第一种正向考虑的区别
if(!vis[i]){
vis[i]=;
for(int j=;j<=color;j++){
if(judge(i,j)){
col[i]=j;
if(dfs(num+,color))
return true;
}
}
vis[i]=;
}
}
return false;
}
int main()
{
while(scanf("%d",&n),n){
memset(graph,,sizeof(graph));
for(int i=;i<n;i++){
cin>>ch;for(int j=;j<strlen(ch);j++)
graph[ch[]-'A'][ch[j]-'A']=;
}
for(int i=;i<=;i++){
memset(vis,,sizeof(vis));
if(dfs(,i)){
if(i==)
printf("1 channel needed.\n");
else
printf("%d channels needed.\n",i);
break;
}
}
}
}

暴力搜索

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
bool graph[][];
char ch[];
int col[],colornum;
int n,mincolor;
bool judge(int x,int y)
{
for(int i=;i<n;i++){
if(graph[x][i])
if(col[i]==y) return false;
}
return true;
}
bool flag;
void dfs(int i)
{
if(flag) return;
if(i==n){//剪枝
mincolor=colornum;
flag=;
}//判断用过的颜色里是否有可用的
for(int j=;j<=colornum;j++){
if(judge(i,j)){
col[i]=j;
dfs(i+);
col[i]=;//还原到dfs(i+1)之前的状态,因为可能还可以染其他颜色
}
}
colornum++;//上面颜色都不行的话再选用一种新的颜色
col[i]=colornum;
dfs(i+);
col[i]=;//还原到dfs(i+1)之前的状态
colornum--;//还原,因为i都没被染色,所以新加的颜色肯定要退回去
}
int main()
{
while(scanf("%d",&n),n){
memset(graph,,sizeof(graph));
for(int i=;i<n;i++){
cin>>ch;
for(int j=;j<strlen(ch);j++)
graph[ch[]-'A'][ch[j]-'A']=;
}
flag=,colornum=;
memset(col,,sizeof(col));
dfs();//注意 不是dfs(1),因为第一个点的编号为0
if(mincolor==)
printf("1 channel needed.\n");
else
printf("%d channels needed.\n",mincolor);
}
}

PKU 1129 Channel Allocation(染色问题||搜索+剪枝)的更多相关文章

  1. 迭代加深搜索 POJ 1129 Channel Allocation

    POJ 1129 Channel Allocation Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 14191   Acc ...

  2. POJ 1129:Channel Allocation 四色定理+暴力搜索

    Channel Allocation Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 13357   Accepted: 68 ...

  3. POJ 1129 Channel Allocation(DFS)

    Channel Allocation Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 13173   Accepted: 67 ...

  4. POJ 1129 Channel Allocation DFS 回溯

    Channel Allocation Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 15546   Accepted: 78 ...

  5. poj 1129 Channel Allocation ( dfs )

    题目:http://poj.org/problem?id=1129 题意:求最小m,使平面图能染成m色,相邻两块不同色由四色定理可知顶点最多需要4种颜色即可.我们于是从1开始试到3即可. #inclu ...

  6. POJ 1129 Channel Allocation 四色定理dfs

    题目: http://poj.org/problem?id=1129 开始没读懂题,看discuss的做法,都是循环枚举的,很麻烦.然后我就决定dfs,调试了半天终于0ms A了. #include ...

  7. poj 1129 Channel Allocation

    http://poj.org/problem?id=1129 import java.util.*; import java.math.*; public class Main { public st ...

  8. poj 1129 Channel Allocation(图着色,DFS)

    题意: N个中继站,相邻的中继站频道不得相同,问最少需要几个频道. 输入输出: Sample Input 2 A: B: 4 A:BC B:ACD C:ABD D:BC 4 A:BCD B:ACD C ...

  9. poj1129 Channel Allocation(染色问题)

    题目链接:poj1129 Channel Allocation 题意:要求相邻中继器必须使用不同的频道,求需要使用的频道的最少数目. 题解:就是求图的色数,这里采用求图的色数的近似有效算法——顺序着色 ...

随机推荐

  1. ORACLE之常用FAQ V1.0

    [B]第一部分.SQL&PL/SQL[/B][Q]怎么样查询特殊字符,如通配符%与_[A]select * from table where name like 'A\_%' escape ' ...

  2. zoj 3370(二分+二分图染色)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3912 思路:二分覆盖直径,然后判断是否有冲突(即距离小于等于直径的不 ...

  3. SurvivalShooter学习笔记(九.游戏暂停、结束)

    这里先补充一个得分管理器: 玩家得分设置成一个静态变量: public class ScoreManager : MonoBehaviour { public static int score; // ...

  4. 介绍MFC框架中涉及到的设计模式(二)

    接着上一篇<介绍MFC框架中涉及到的设计模式(一)>介绍 单例模式(Singleton Pattern) 单例模式是一种经常使用的软件设计模式.在它的核心结构中仅仅包括一个被称为单例类的特 ...

  5. Linux下的高级拾色器—Pick

    导读 虽然大多数设计师都在使用 Mac,但也有一少部分在使用 Windows 甚至是 Linux 系统.在 Mac 和 Windows 中都有非常丰富的拾色器工具或插件可用,反而在开源界中这类颜色选择 ...

  6. SSH电力项目九--运行监控首页显示

    需求:在首页显示出设备运行情况,并去掉<br>换行符,每隔十分钟刷新一次页面. ElecMenuAction.java 首先注入运行监控service public class ElecM ...

  7. vue 把后台返回的json拼接成excel并下载

    先封装一下生成excel的方法 downfile.js export default { data() { return {} }, components: {}, created() { }, me ...

  8. 170407、java基于nio工作方式的socket通信

    客户端代码: /** * */ package com.bobohe.nio; import java.io.BufferedReader; import java.io.IOException; i ...

  9. 如何自定义JSTL标签与SpringMVC 标签的属性中套JSTL标签报错的解决方法

    如何自定义JSTL标签 1.创建一个类,从SimpleTagSupport继承 A) 通过继承可以获得当前JSP页面上的对象,如JspContext I) 实际上可以强转为PageContext II ...

  10. java面试基础题------》抽象类和接口有什么异同

    划重点!!!! 1.抽象类(abstract class)和接口(interface)有什么异同? 相同点 * 都不能被直接实例化,都可以通过继承实现其抽象方法. * 都是面向抽象编程的技术基础,实现 ...