http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1508

题意:地图中四联通的块是一个国家,A和B每个人可以涂两种颜色,且B不能涂超过5次,相邻的国家不能涂一样的颜色,并且最后每种颜色都要用上,问共有多少种涂色方案。

思路:先DFS处理出图中的国家,然后先用一个邻接矩阵存下相邻的国家(直接用邻接表会有重边),然后再用邻接表存图。数方案个数的时候,假设共有a,b,c,d这四种颜色,A可以涂a,b,B可以涂c,d。因为颜色之间没有差异,所以A先涂a颜色,B先涂c颜色,那么和A先涂b颜色,B先涂c或者d颜色是一样的。所以暂时假设A先涂a颜色,B先涂c颜色,然后利用平时判断二分图一样,去染色,记得染完色之后col[num]要置0。通过约束条件得到答案后,因为有先涂a-c,a-d,b-c,b-d这四种情况,所以最后答案*4。

 #include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <string>
#include <iostream>
#include <stack>
#include <map>
#include <queue>
#include <set>
using namespace std;
typedef long long LL;
#define N 40
#define INF 0x3f3f3f3f
struct node {
int v, nxt;
}edge[N*N*];
int n, m, vis[N][N], tu[N][N], cnt, col[N], head[N], ans, tot, dx[] = {, -, , }, dy[] = {, , , -};
char mp[N][N]; bool check(int x, int y) { if( < x && x <= n && < y && y <= m) return true; return false; } void Add(int u, int v) { edge[tot].v = v; edge[tot].nxt = head[u]; head[u] = tot++; } void DFS(int x, int y, char c) {
for(int i = ; i < ; i++) {
int nx = dx[i] + x, ny = dy[i] + y;
if(check(nx, ny) && !vis[nx][ny] && mp[nx][ny] == c) {
vis[nx][ny] = cnt; DFS(nx, ny, c);
}
}
} bool judge(int u, int c) {
for(int i = head[u]; ~i; i = edge[i].nxt)
if(col[edge[i].v] == c) return false;
return true;
} void dfs(int num, int a, int b, int c, int d) {
if(num == cnt + ) {
if(a && b && c && d) ans++;
return ;
}
if(judge(num, )) {
col[num] = ;
dfs(num + , a + , b, c, d);
col[num] = ;
}
if(a > && judge(num, )) {
col[num] = ;
dfs(num + , a, b + , c, d);
col[num] = ;
}
if(c + d < && judge(num, )) {
col[num] = ;
dfs(num + , a, b, c + , d);
col[num] = ;
}
if(c + d < && c && judge(num, )) {
col[num] = ;
dfs(num + , a, b, c, d + );
col[num] = ;
}
} int main()
{
int cas = ;
while(~scanf("%d%d", &n, &m)) {
for(int i = ; i <= n; i++) scanf("%s", mp[i] + );
memset(head, -, sizeof(head));
memset(vis, , sizeof(vis));
memset(col, , sizeof(col));
memset(tu, , sizeof(tu));
tot = cnt = ans = ;
for(int i = ; i <= n; i++)
for(int j = ; j <= m; j++)
if(!vis[i][j]) { cnt++; vis[i][j] = cnt; DFS(i, j, mp[i][j]); }
for(int i = ; i <= n; i++) {
for(int j = ; j <= m; j++) {
if(vis[i-][j] && vis[i-][j] != vis[i][j]) tu[vis[i][j]][vis[i-][j]] = tu[vis[i-][j]][vis[i][j]] = ;
if(vis[i][j-] && vis[i][j-] != vis[i][j]) tu[vis[i][j-]][vis[i][j]] = tu[vis[i][j]][vis[i][j-]] = ;
}
}
for(int i = ; i <= cnt; i++)
for(int j = ; j <= cnt; j++)
if(i != j && tu[i][j]) Add(i, j);
dfs(, , , , );
printf("Case %d: %d\n", cas++, ans * );
}
return ;
}

CSU 1508:地图的四着色(DFS+剪枝)的更多相关文章

  1. [csu1508 地图的四着色]二分图染色

    抽象后的题意:给一个不超过30个点的图,A从中选不超过5个点涂红绿两种颜色,B用黑白两种颜色把剩下的涂完,任意一条边两端的颜色不同,求每种颜色至少用涂一次的方案数 思路:枚举A涂的点的集合,将原图分成 ...

  2. DFS+剪枝 HDOJ 5323 Solve this interesting problem

    题目传送门 /* 题意:告诉一个区间[L,R],问根节点的n是多少 DFS+剪枝:父亲节点有四种情况:[l, r + len],[l, r + len - 1],[l - len, r],[l - l ...

  3. 数据结构与算法实验题 9.1 K 歌 DFS+剪枝

    数据结构与算法实验题 K 歌 ★实验任务 3* n 个人(标号1~ 3 * n )分成 n 组 K 歌.有 m 个 3 人组合,每个组合都对应一个分数,你能算出最大能够得到的总分数么? ★数据输入 输 ...

  4. *HDU1455 DFS剪枝

    Sticks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  5. POJ 3009 DFS+剪枝

    POJ3009 DFS+剪枝 原题: Curling 2.0 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16280 Acce ...

  6. poj 1724:ROADS(DFS + 剪枝)

    ROADS Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10777   Accepted: 3961 Descriptio ...

  7. DFS(剪枝) POJ 1011 Sticks

    题目传送门 /* 题意:若干小木棍,是由多条相同长度的长木棍分割而成,问最小的原来长木棍的长度: DFS剪枝:剪枝搜索的好题!TLE好几次,终于剪枝完全! 剪枝主要在4和5:4 相同长度的木棍不再搜索 ...

  8. HDU 5952 Counting Cliques 【DFS+剪枝】 (2016ACM/ICPC亚洲区沈阳站)

    Counting Cliques Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  9. HDU 5937 Equation 【DFS+剪枝】 (2016年中国大学生程序设计竞赛(杭州))

    Equation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

随机推荐

  1. WPF中TextBlock文本换行与行间距

    原文:WPF中TextBlock文本换行与行间距 换行符: C#代码中:\r\n 或  \r 或 \n XAML中: 或 注:\r 回车 (carriage return 缩写),\n 新行 (new ...

  2. WPF ValidationRule的特点(默认目标-源才校验)

    默认是当目标发生改变时候,通过绑定改变源时候进行校验,因为WPF认为源是安全的,如果想让源改变时候,也进行校验则设置验证规则的ValidatesOnTargetUpdated =true using ...

  3. MVC EF 导航属性

    @model IQueryable<EFExam.Models.CategoryProductViewModel>@{    Layout = null;}<!DOCTYPE htm ...

  4. C#基于用户和角色的验证,服务端web 客户端wpf

    应用程序服务 <?xml version="1.0"?> <!--  For more information on how to configure your ...

  5. c# 安装windows服务

    C# windows服务: 第一种 :通过cmd命令安装.卸载.启动和停止Windows Service(InstallUtil.exe) 步骤: 1.运行--〉cmd:打开cmd命令框 2.在命令行 ...

  6. ArchLinux 安装记录

    主要步骤 下载镜像及刻录 开机安装 联网 编辑镜像站文件 分区 格式化分区并挂载 安装基本操作系统 配置基础操作系统 引导系统 用户管理 网络配置 安装Gonme桌面环境 其他优化 开始准备 下载镜像 ...

  7. 基于VUE实现的新闻后台管理系统-二

    基础环境及最后的开发效果已完成说明,接下来就开始配置. ¶npm初始化 新建项目文件夹VueDemo,在其内执行如下脚本 npm init -y 安装vue-cli构建包 yarn add vue-c ...

  8. 手机软件没过多久就删了 APP到底得了什么病?

    直击现场 PC互联网时代正渐行渐远,移动互联网的创业浪潮汹涌而至.2014年,中国成为拥有智能手机用户最多的国家,而疯狂生长的APP正占据新的风口.据了解,目前我国主要应用商店的APP已累计超过400 ...

  9. 每一位想有所成就的程序员都必须知道的15件事(走不一样的路,要去做,实践实践再实践,推销自己,关注市场)good

    从 为之漫笔作者:为之漫笔 有超过 100 人喜欢此条目 原文地址:How to advance your career? Read the Passionate Programmer! 我刚看完Ch ...

  10. jsp中的指令与动作

    JSP中的三种命令指令分别是page.include.taglib JSP中的动作元素包括:include.forward.useBean.getProperty.setProperty.plugin ...