poj2148
题意:给出若干个没有公共面积的多边形,几个多边形可能属于同一个国家,要求给这个地图染色,同一个国家用相同的颜色,相邻国家不能用相同颜色。问最少需要多少种颜色。
分析:计算几何+搜索。先判断哪些多边形是相邻的(这里只有一个公共点的不算相邻)。对于两个多边形,两两比较他们所有的边,看是否有重合部分。建好图后,枚举颜色数量(也可二分查找),并判断这些颜色是否可行。判断过程用搜索。搜索的方法是,n个点,第一层确定第一个点的颜色,第二层确定第二个点的颜色,以此类推,每次要向下递归前先判断当前染色是否产生冲突。而不是向二分图染色那样染搜相邻的点。
#include <cstdio>
#include <map>
#include <cstring>
#include <string>
using namespace std; #define zero(x) (((x)>0?(x):-(x))<eps)
#define eps 1.0E-8
#define MAX_POINT_NUM 105
#define MAX_POLYGON_NUM 105
#define MAX_TERR_NUM 15 int double_cmp(double a)
{
if (zero(a))
return ;
return a > ? : -;
} struct Edge
{
int v;
int length;
Edge()
{}
Edge(int v, int length):v(v), length(length)
{}
}; struct Point
{
double x,y;
Point()
{}
Point(double x, double y):x(x), y(y)
{}
Point operator - (const Point &a) const
{
return Point(x - a.x, y - a.y);
}
bool operator == (const Point &a) const
{
return x == a.x && y == a.y;
}
}; double cross_product(Point a, Point b)
{
return a.x * b.y - b.x * a.y;
} double cross_product(Point p0, Point p1, Point p2)
{
return cross_product(p1 - p0, p2 - p0);
} double dot_product(Point a, Point b)
{
return a.x * b.x + a.y * b.y;
} double dot_product(Point p0, Point p1, Point p2)
{
return dot_product(p1 - p0, p2 - p0);
} struct Line
{
Point a, b;
Line()
{}
Line(Point a, Point b):a(a), b(b)
{}
bool operator == (const Line &l) const
{
return l.a == a && l.b == b;
}
}; bool points_inline(Point p1, Point p2, Point p3)
{
return zero(cross_product(p1, p2, p3));
} bool same_side(Point p1, Point p2, Line l)
{
return cross_product(l.a, p1, l.b) * cross_product(l.a, p2, l.b) > eps;
} bool point_online_in(Point p, Line l)
{
return zero(cross_product(p, l.a, l.b)) && double_cmp(dot_product(p, l.a, l.b)) < ;
} bool overlap(Line u, Line v)
{
if (u == v || (u.a == v.b && u.b == v.a))
return true;
if (!points_inline(u.a, u.b, v.a) || !points_inline(u.a, u.b, v.b))
return false;
bool ret = point_online_in(u.a, v);
ret = ret || point_online_in(u.b, v);
ret = ret || point_online_in(v.a, u);
ret = ret || point_online_in(v.b, u);
return ret;
} struct Polygon
{
Point point[MAX_POINT_NUM];
int id;
int point_num;
}polygon[MAX_POLYGON_NUM]; map<string, int> territory_id;
int polygon_num;
int territory_cnt;
int color[MAX_POLYGON_NUM];
bool graph[MAX_TERR_NUM][MAX_TERR_NUM]; void input()
{
territory_id.clear();
territory_cnt = ;
for (int i = ; i < polygon_num; i++)
{
char territory_name[];
scanf("%s", territory_name);
string name = string(territory_name);
if (territory_id.find(name) == territory_id.end())
{
territory_id[name] = ++territory_cnt;
}
polygon[i].point_num = ;
polygon[i].id = territory_id[name];
while ()
{
int j = polygon[i].point_num;
scanf("%lf", &polygon[i].point[j].x);
if (polygon[i].point[j].x == -)
break;
scanf("%lf", &polygon[i].point[j].y);
polygon[i].point_num++;
}
}
} bool neighbour(Polygon &a, Polygon &b)
{
for (int i = ; i < a.point_num; i++)
{
for (int j = ; j < b.point_num; j++)
{
Line l1 = Line(a.point[i], a.point[(i + ) % a.point_num]);
Line l2 = Line(b.point[j], b.point[(j + ) % b.point_num]);
if (overlap(l1, l2))
return true;
}
}
return false;
} void create_graph()
{
memset(graph, , sizeof(graph));
for (int i = ; i < polygon_num - ; i++)
{
for (int j = i + ; j < polygon_num; j++)
{
int a = polygon[i].id;
int b = polygon[j].id;
a--;
b--;
if (a == b || graph[a][b])
continue;
if (neighbour(polygon[i], polygon[j]))
graph[a][b] = graph[b][a] = true;
}
}
} bool ok(int u)
{
for (int i = ; i < territory_cnt; i++)
if (i != u && graph[i][u])
{
if (color[u] == color[i])
return false;
}
return true;
} bool dfs(int color_num, int u)
{
if (u == territory_cnt)
{
return true;
}
for (int i = ; i < color_num; i++)
{
color[u] = i;
if (!ok(u))
continue;
if (dfs(color_num, u + ))
return true;
}
color[u] = -;
return false;
} int main()
{
while (scanf("%d", &polygon_num), polygon_num)
{
input();
create_graph();
int ans = ;
while (ans <= )
{
ans++;
memset(color, -, sizeof(color));
color[] = ;
if (dfs(ans, ))
{
printf("%d\n", ans);
break;
}
}
}
return ;
}
poj2148的更多相关文章
- poj分类 很好很有层次感。
初期: 一.基本算法: (1)枚举. (poj1753,poj2965) (2)贪心(poj1328,poj2109,poj2586) (3)递归和分治法. ( ...
- 【转】POJ题目分类推荐 (很好很有层次感)
OJ上的一些水题(可用来练手和增加自信) (poj3299,poj2159,poj2739,poj1083,poj2262,poj1503,poj3006,poj2255,poj3094)初期: 一. ...
- 【转】ACM训练计划
[转] POJ推荐50题以及ACM训练方案 -- : 转载自 wade_wang 最终编辑 000lzl POJ 推荐50题 第一类 动态规划(至少6题, 和 必做) 和 (可贪心) (稍难) 第二类 ...
- POJ 题目分类(转载)
Log 2016-3-21 网上找的POJ分类,来源已经不清楚了.百度能百度到一大把.贴一份在博客上,鞭策自己刷题,不能偷懒!! 初期: 一.基本算法: (1)枚举. (poj1753,poj2965 ...
- (转)POJ题目分类
初期:一.基本算法: (1)枚举. (poj1753,poj2965) (2)贪心(poj1328,poj2109,poj2586) (3)递归和分治法. (4)递推. ...
- acm常见算法及例题
转自:http://blog.csdn.net/hengjie2009/article/details/7540135 acm常见算法及例题 初期:一.基本算法: (1)枚举. (poj17 ...
- poj分类
初期: 一.基本算法: (1)枚举. (poj1753,poj2965) (2)贪心(poj1328,poj2109,poj2586) (3)递归和分治法. ( ...
- 转载 ACM训练计划
leetcode代码 利用堆栈:http://oj.leetcode.com/problems/evaluate-reverse-polish-notation/http://oj.leetcode. ...
- ACM算法总结及刷题参考
参考:http://bbs.byr.cn/#!article/ACM_ICPC/11777 OJ上的一些水题(可用来练手和增加自信)(poj3299,poj2159,poj2739,poj1083,p ...
随机推荐
- Linux下使用NTFS格式移动硬盘
https://zhidao.baidu.com/question/66517344.html https://zhidao.baidu.com/question/586036510.html htt ...
- K8S 使用NFS 创建PV和PVC的例子 学习From https://blog.csdn.net/xts_huangxin/article/details/51494472
1. 获取资料 网址: https://blog.csdn.net/xts_huangxin/article/details/51494472 感谢原作者 这里面 按照自己的机器情况进行了学习模仿 ...
- Jquery 获取屏幕及滑块及元素的高度及距离
alert($(window).height()); //浏览器时下窗口可视区域高度 alert($(document).height()); //浏览器时下窗口文档的高度 alert($(docum ...
- const和typedef的常见用法详解
一.说说const 一般而言,const主要是用来防止定义的对象再次被修改,定义对象变量时要初始化变量. 常见用法如下: 1.用于定义常量变量,这样这个变量在后面就不可以再被修改 const int ...
- IntelliJ IDEA中文乱码问题
转自 https://blog.csdn.net/m0_37893932/article/details/78280663 1 file->settings->appearence里面有 ...
- Python之路:Python操作 RabbitMQ、Redis、Memcache、SQLAlchemy
Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度 ...
- kubeadm安装部署kubernetes 1.11.3(单主节点)
由于此处docker代理无法使用,因此,请各位设置有效代理进行部署,勿使用文档中的docker代理.整体部署步骤不用改动.谢谢各位支持. 1.部署背景 操作系统版本:CentOS Linux rele ...
- 知乎网的CSS命名规律研究
笔者是一名Java程序员,前端css和图片本不是我的工作,亦不是我的强项.但很多时候,公司并没有合适的美工,只有自己动手.一般的css技术,倒是没有问题,定位,盒子,浮动,布局等等,都能做.但每每完成 ...
- NOIP2017 列队——动态开点线段树
Description: Sylvia 是一个热爱学习的女♂孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有n×m名学生,方阵的行数为 ...
- HTML5 快速学习二 Canvas
本篇文章开始讲解HTML5的核心功能之一:Canvas 通过Canvas可以动态生成和展示图形.图表.图像以及动画. Canvas API功能非常多,我们将讨论最常用的功能. 我们先新建一个canva ...