CSU 1508 地图的四着色
来源:互联网 发布:linux解压文件命令 编辑:程序博客网 时间:2024/05/24 16:13
1508: 地图的四着色
Time Limit: 20 Sec Memory Limit: 128 Mb Submitted: 230 Solved: 105
Description
有一个R行C列的网格地图,每个国家是一个四连通区域。你的任务是用红,绿,蓝,黄四种颜色给地图着色,使得相邻国家的颜色不同。
一个人着色比较无趣,所以你想请女朋友陪你一起涂——你涂红绿,她涂蓝黄。当然,绅士是不会让让女朋友受累的,所以她最多只需涂5个国家(恰好5个也行)。
你的任务是统计有多少种着色的方法。注意,每个颜色都至少要用一次。
Input
输入包含不超过100组数据。每组数据第一行为两个整数R和C (1<=R,C<=20),即网格的行数和列数。以下R行每行C个大写字母。相同字母所组成的四连通区域代表一个国家。输入保证国家数目不超过30,并且大多数测试点的国家数都比较小。
Output
对于每组数据,输出测试点编号和着色方案数。
Sample Input
2 4AABBBBAA1 5ABABA4 7AABAABBABBCCCBBBAACBBCCABBAC
Sample Output
Case 1: 24Case 2: 144Case 3: 3776
Hint
思路:先对图中进行bfs为每个国家编号,暴力去找出每个国家都与哪些国家相邻并建边,之后就产生了一个新图,就把问题转化为有多少种染色方案能使得相连的点的颜色两两互不相同。正解应该是二分图染色,不过用点组合数学加上dfs也是能比较快的跑出来。
组合思想:我们可以强行让男的第一次先涂第一种颜色,女的第一次先涂第三种颜色。(对于此题,先涂哪一个颜色都是等价的,所以结果是2*2倍)(来源于:http://blog.csdn.net/acm_cxq/article/details/52224876)
要注意的是答案会爆int
Source
湖南省第十届大学生计算机程序设计竞赛#include <cstdio>#include <cstring>#include <queue>using namespace std;struct jj{ int x,y;};struct kk{ int v,next;}w[900];//新图int h[30],numw,mpid[20][20],n,m,num,v[30],walk[4][2]={{0,1},{0,-1},{1,0},{-1,0}};long long sum;char mp[20][21];void insert(int u,int v){ w[numw].v=v; w[numw].next=h[u]; h[u]=numw++;}void bfs(int x,int y){ int i; struct jj s,pos; queue<struct jj>q; mpid[x][y]=num; s.x=x; s.y=y; q.push(s); while(q.empty()==0) { s=q.front(); q.pop(); for(i=0;4>i;i++) { pos.x=s.x+walk[i][0]; pos.y=s.y+walk[i][1]; if(pos.x>=0&&pos.x<n&&pos.y>=0&&pos.y<m&&mpid[pos.x][pos.y]==-1&&mp[x][y]==mp[pos.x][pos.y]) { mpid[pos.x][pos.y]=num; q.push(pos); } } }}int judge(int deep,int kind){ int i; for(i=h[deep];i!=-1;i=w[i].next) { if(v[w[i].v]==kind)//使用的颜色不符合条件 { return 0; } } return 1;}void dfs(int deep,int buff,int status){ int i; if(deep==num) { if(status==15)//当状态为15的时候说明每一种颜色都用上了 { sum++; } return; } if(judge(deep,1)==1) { v[deep]=1; dfs(deep+1,buff,status|1); v[deep]=0; } if(judge(deep,2)==1&&(status&1)!=0) { v[deep]=2; dfs(deep+1,buff,status|2); v[deep]=0; } if(buff==0) { return; } if(judge(deep,3)==1) { v[deep]=3; dfs(deep+1,buff-1,status|4); v[deep]=0; } if(judge(deep,4)==1&&(status&4)!=0) { v[deep]=4; dfs(deep+1,buff-1,status|8); v[deep]=0; }}int main(){ int i,i1,i2,i3,x,y; for(i=1;scanf("%d %d",&n,&m)!=EOF;i++) { for(i1=0;n>i1;i1++) { scanf("%s",mp[i1]); } memset(mpid,-1,sizeof(mpid));//每个点所属的国家编号 memset(h,-1,sizeof(h)); num=0; sum=0; numw=0; for(i1=0;n>i1;i1++) { for(i2=0;m>i2;i2++) { if(mpid[i1][i2]==-1) { bfs(i1,i2);//bfs为国家编号 num++; } } } for(i1=0;n>i1;i1++) { for(i2=0;m>i2;i2++) { for(i3=0;4>i3;i3++)//暴力找相邻国家 { x=i1+walk[i3][0]; y=i2+walk[i3][1]; if(x>=0&&x<n&&y>=0&&y<m&&mpid[i1][i2]!=mpid[x][y]) { insert(mpid[i1][i2],mpid[x][y]); } } } } memset(v,0,sizeof(v));//初始化所有点都未上色 dfs(0,5,0); printf("Case %d: %lld\n",i,sum*4); } return 0;}
阅读全文
0 0
- CSU 1508 地图的四着色
- CSU-1508 地图的四着色【Bfs+Dfs+思维剪枝】
- csu 1508 地图的四着色(BFS,DFS,巧妙剪枝)
- 每日三题-Day6-C(CSU 1508 地图的四着色 巧妙剪枝搜索dfs)
- 地图的四着色 中南1508
- CSU_1508_地图的四着色
- csu_1508_地图的四着色
- uscoj:1346 & csuoj:1508 地图的四着色
- 地图四着色问题
- csu1508 地图的四着色(剪枝+BFS DFS)
- CSU 1007 矩形着色
- 四色着色的证明
- 地图着色程序
- poj_1129_地图着色?
- 地图着色问题
- CSU 1007 矩形着色 so easy
- 有趣的题目:四色着色问题算法研究
- SimpleRenderer着色法渲染地图
- 我与Linux系统
- 在网页上播放多种后缀的视频文件的临时解决方案
- macOS 修改网卡地址出现basicipv6validationerror怎么改
- linux之进程管理详解
- Xshell常用命令
- CSU 1508 地图的四着色
- Android签名证书jks转换成signapk使用的分离模式
- Deep Learning(深度学习)学习笔记整理系列之(七)
- Java多线程
- 孪生素数
- caffe调试 ubuntu1404+eclipse
- iOS 10.3无法安装企业In-House APP问题
- 爬虫初探(一),获取一个页面
- Xcode编译包含第三方库时Mach-O错误解决方法