PKU 1129 Channel Allocation(染色问题||搜索+剪枝)
题目大意建模:
一个有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(染色问题||搜索+剪枝)的更多相关文章
- 迭代加深搜索 POJ 1129 Channel Allocation
POJ 1129 Channel Allocation Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 14191 Acc ...
- POJ 1129:Channel Allocation 四色定理+暴力搜索
Channel Allocation Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 13357 Accepted: 68 ...
- POJ 1129 Channel Allocation(DFS)
Channel Allocation Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 13173 Accepted: 67 ...
- POJ 1129 Channel Allocation DFS 回溯
Channel Allocation Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 15546 Accepted: 78 ...
- poj 1129 Channel Allocation ( dfs )
题目:http://poj.org/problem?id=1129 题意:求最小m,使平面图能染成m色,相邻两块不同色由四色定理可知顶点最多需要4种颜色即可.我们于是从1开始试到3即可. #inclu ...
- POJ 1129 Channel Allocation 四色定理dfs
题目: http://poj.org/problem?id=1129 开始没读懂题,看discuss的做法,都是循环枚举的,很麻烦.然后我就决定dfs,调试了半天终于0ms A了. #include ...
- poj 1129 Channel Allocation
http://poj.org/problem?id=1129 import java.util.*; import java.math.*; public class Main { public st ...
- 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 ...
- poj1129 Channel Allocation(染色问题)
题目链接:poj1129 Channel Allocation 题意:要求相邻中继器必须使用不同的频道,求需要使用的频道的最少数目. 题解:就是求图的色数,这里采用求图的色数的近似有效算法——顺序着色 ...
随机推荐
- exif_imagetype() 函数在linux下的php中不存在
1.问题,项目中上传文件使用插件时,windows上支持函数exif_imagetype(),而在linux上不支持. 2.PHP exif_imagetype的本质 PHP exif_imagety ...
- C# 中的treeview绑定数据库(递归算法)
近日面试的给我两道题目,一道是IQ测试,第二个就是题目所言 总共两个表 department(id int not null primary key,parentid int,name char(50 ...
- VC++中CEdit控件实现回车换行
1.通过回车Enter换行: 这里要有两个设置 <1>.将控件的属性设置为Mutilines->true; <2>.将控件的另一个属性设置为Want return-> ...
- IOS7开发~新UI学起(四)
本文转载至 http://blog.csdn.net/lizhongfu2013/article/details/9166193 1.UITableView: UITableViewDelegate ...
- 基于xml文件的格式配置Spring的AOP
用例子直接说明: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http ...
- Error : .onLoad failed in loadNamespace() for 'rJava', details: call: inDL(x, as.logical(local), as.logical(now), ...) error: 无法载入共享目标对象‘D:/Program Files/R/R-3.2.2/library/rJava/libs/x64/rJava.dll
Error : .onLoad failed in loadNamespace() for 'rJava', details: call: inDL(x, as.logical(local), as. ...
- Netty 粘包/半包原理与拆包实战
Java NIO 粘包 拆包 (实战) - 史上最全解读 - 疯狂创客圈 - 博客园 https://www.cnblogs.com/crazymakercircle/p/9941658.html 本 ...
- ROS 笔记
ros的编程范式 - ros认为,linux平台下,机器人的软件由一个个小程序组成,这些小程序称为node,每个小程序负责一部分功能 - ros实现的框架就是,小程序的并发执行+相互通信,程序(进程) ...
- 网络编程 - 1.简单的套接字通信/2.加上通信循环/3.bug修复/4.加上链接循环/5.模拟ssh远程执行命令
1.简单的套接字通信 服务端 ''' 服务端 接电话 客户端 打电话 1.先启动服务端 2.服务端有两种套接字 1.phone 用来干接收链接的 2.conn 用来干收发消息的 ''' import ...
- ntpdate同步更新时间
Linux服务器运行久时,系统时间就会存在一定的误差,一般情况下可以使用date命令进行时间设置,但在做数据库集群分片等操作时对多台机器的时间差是有要求的,此时就需要使用ntpdate进行时间同步 1 ...