题目大意建模:

一个有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. SQL在oracle和SQLserver将查询结果创建为新表的不同之处

    ------在SQL中,将查询的结果创建为新表是如下这样的 select distinct t1.column1,.t2.column2 into table3 from table1.t1 join ...

  2. numpy生成随机数

    如果你想说,我不想知道里面的逻辑和实现方法,只想要python生成随机数的代码,请移步本文末尾,最简单的demo帮你快速获取实现方法. 先开始背景故事说明: 在数据分析中,数据的获取是第一步,nump ...

  3. 统计nginx进程占用的物理内存

    #!/usr/bin/env python #-*- coding:utf-8 -*- ''' 统计nginx进程占用的物理内存 ''' import os import sys import sub ...

  4. [libwww-perl]——POST方法的使用

    libwww-perl是我在学习varnish的时候遇到的一个工具. 具体libwww-perl是干什么的,可以参考官网https://github.com/libwww-perl/libwww-pe ...

  5. Android 全局异常处理(一)

    from:http://onewayonelife.iteye.com/blog/1147533 from:http://blog.csdn.net/liuhe688/article/details/ ...

  6. HQL的检索方式

    HQL是面向持久化类的,所以需要查询表的字段都要用持久化类指定例如 String hql = "SELECT e.email, e.salary, e.dept FROM Employee ...

  7. maven (profiles)装载不同环境所需的配置文件

    引子: maven与java的联系在今天的项目已经是不可分割的 ,但是不同的项目有各具特色的项目结构,不同的项目结构使用了不同的maven插件,想要了解一个项目的项目结构,或者自己构建一个具有成熟结构 ...

  8. TCP implements its own acknowledgment scheme to guarantee successful data delivery

    wTCP本身已经确保传输的成功性. HTTP The Definitive Guide 4.2.4 Delayed Acknowledgments Because the Internet itsel ...

  9. Spark 源码分析 -- Stage

    理解stage, 关键就是理解Narrow Dependency和Wide Dependency, 可能还是觉得比较难理解 关键在于是否需要shuffle, 不需要shuffle是可以随意并发的, 所 ...

  10. Storm-源码分析- Messaging (backtype.storm.messaging)

    先定义两个接口和一个类 TaskMessage类本身比较好理解, 抽象storm的message格式 对于IContext, 注释也说了, 定义messaging plugin, 通过什么渠道去发送m ...