题目大意建模:

一个有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. linux改动登陆主机提示信息

    寻常管理着130多台Linux物理主机.真正搞清楚每一台主机的IP信息.应用部署比較麻烦! 所以在部署之初,必须规划好: 写一个脚本.把主机IP.管理员联系方法,应用部署等主机信息放在.sh里面 sh ...

  2. 蓝桥杯 历届试题 剪格子(dfs搜索)

    历届试题 剪格子 时间限制:1.0s   内存限制:256.0MB 问题描述 如下图所示,3 x 3 的格子中填写了一些整数. +--*--+--+ |* || +--****--+ ||* | ** ...

  3. mysql查询各种类型的前N条记录

    mysql查询各种类型的前N条记录,将3改为N(需查询条数)即可  (select * from event_info where event_type = 1  limit 3)union all( ...

  4. C# 直接调用非托管代码的方法

    C# 代码有以下两种可以直接调用非托管代码的方法: 直接调用从 DLL 导出的函数. 调用 COM 对象上的接口方法. 对于这两种技术,都必须向 C# 编译器提供非托管函数的声明,并且还可能需要向 C ...

  5. Codeforces Round #296 (Div. 2) B. Error Correct System

    B. Error Correct System time limit per test 2 seconds memory limit per test 256 megabytes input stan ...

  6. Hibernate_day04--课程安排_Hibernate查询方式_对象导航查询_OID查询

    Hibernate_day04 上节内容 今天内容 Hibernate查询方式 对象导航查询 OID查询 HQL查询 查询所有 条件查询 排序查询 分页查询 投影查询 聚集函数使用 QBC查询 查询所 ...

  7. 剑指 offer set 25 求 1+2+...+n

    题目 要求不能使用乘除法, for, while, if else, switch, case 等关键字 思路 1. 循环已经命令禁止, 禁用 if, 意味着递归也不能使用. 但即便如此, 我们仍然要 ...

  8. JB开发之问题汇总 [jailbreak,越狱技术]

    1.升级到Mac 10.9.1,Xcode 升级到5出现的问题: 1)升级前要做的事情: ①升级/重新安装iOSOpenDev,在终端输入 xcode-select --switch (xcode_d ...

  9. vue-router scrollBehavior无效的问题

    在使用vue做单页面应用开发时候 使用vue-router作为路由控制器  在使用过程中发现每个页面打开都在原来的位置 不能返回到页面顶部位置 ,然后查看api文档 滚动行为  发现如下代码: con ...

  10. HDU 1866 A + B forever!

    A + B forever! Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...