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. 首个 C++ 编译器诞生 30 周年了,来听听 C++ 之父畅谈 C++

    原文  http://www.iteye.com/news/31076   C++ 之父 Bjarne Stroustrup 在 cfront 诞生 30 周年的访谈. 整整30年前,CFront 1 ...

  2. Linux之tail命令实时收集[纠正误解]

    tail [OPTION]... [FILE]... -c, --bytes=K            output the last K bytes; alternatively, use -c + ...

  3. XF 定制图片

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  4. 计算机网络OSI参考模型与tcp/ip四层模型

    OSI参考模型--7层 1层物理层:主要定义物理设备标准,如网线的接口类型.光线的接口类型.各种传输介质的传输速率等.它的主要作用是传输比特流(就是由1.0转化为电流强弱来进行传输,到达目的地后在转化 ...

  5. WPF中DataGrid自定义实现最后一行下面跟一个汇总行,类似MT4

    1.先看MT4实现的效果:(图中红框部分),其实就是DataGrid在最后一行下面跟一个汇总的显示条 2.看我WPF实现的效果,汇总行中的数据可以绑定哦!效果图如下: 我扩展了一下DataGrid控件 ...

  6. vs2017 cordova调试ios app

    https://docs.microsoft.com/en-us/visualstudio/cross-platform/tools-for-cordova/first-steps/ios-guide ...

  7. ASP如何实现注册后发送激活邮件?

    <% Sub Sendemail(title,content,email) Set jmail = Server.CreateObject("JMAIL.Message") ...

  8. Android签名打包

    生成正式的签名APK文件 1.使用AndroidStudio生成: 点击导航栏上的Build-->Generate Signed APK,弹出创建签名APK对话框(首次点击可能会提示输入操作系统 ...

  9. 邮件带附件和html格式

    1. 发送有附件的邮件需要添加一个附件类Attachment,这个附件可以为文件和图片: Attachment attach = new Attachment(“文件路径”");//文件 A ...

  10. MinGW版Qt如何搭建lua环境?(详细步骤)

    操作系统是windows,lua是Lua for Windows 5.1.4包含了这三个头文件 <ignore_js_op>  在.pro里加了includepath: <ignor ...