HDU 1815, POJ 2749 Building roads

题目链接HDU
题目链接POJ

题意:
有n个牛棚, 还有两个中转站S1和S2, S1和S2用一条路连接起来。

为了使得随意牛棚两个都能够有道路联通,如今要让每一个牛棚都连接一条路到S1或者S2。

有a对牛棚互相有仇恨,所以不能让他们的路连接到同一个中转站。

还有b对牛棚互相喜欢,所以他们的路必须连到同一个中专站。

道路的长度是两点的曼哈顿距离。
问最小的随意两牛棚间的距离中的最大值是多少?

思路:二分距离。考虑每两个牛棚之间4种连边方式,然后依据二分的长度建立表达式,然后跑2-sat推断就可以

代码:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;const int MAXNODE = 505;struct TwoSet {int n;vector<int> g[MAXNODE * 2];bool mark[MAXNODE * 2];int S[MAXNODE * 2], sn;void init(int tot) {n = tot * 2;for (int i = 0; i < n; i += 2) {g[i].clear();g[i^1].clear();}memset(mark, false, sizeof(mark));}void add_Edge(int u, int uval, int v, int vval) {u = u * 2 + uval;v = v * 2 + vval;g[u^1].push_back(v);g[v^1].push_back(u);}void delete_Edge(int u, int uval, int v, int vval) {u = u * 2 + uval;v = v * 2 + vval;g[u^1].pop_back();g[v^1].pop_back();}bool dfs(int u) {if (mark[u^1]) return false;if (mark[u]) return true;mark[u] = true;S[sn++] = u;for (int i = 0; i < g[u].size(); i++) {int v = g[u][i];if (!dfs(v)) return false;}return true;}bool solve() {for (int i = 0; i < n; i += 2) {if (!mark[i] && !mark[i + 1]) {sn = 0;if (!dfs(i)){for (int j = 0; j < sn; j++)mark[S[j]] = false;sn = 0;if (!dfs(i + 1)) return false;}}}return true;}
} gao;const int N = 505;
int n, a, b;struct Point {int x, y;void read() {scanf("%d%d", &x, &y);}
} s1, s2, p[N], A[N * 2], B[N * 2];int dis(Point a, Point b) {int dx = a.x - b.x;int dy = a.y - b.y;return abs(dx) + abs(dy);
}int g[N][N][4];bool judge(int d) {gao.init(n);for (int i = 0; i < a; i++) {gao.add_Edge(A[i].x - 1, 0, A[i].y - 1, 0);gao.add_Edge(A[i].x - 1, 1, A[i].y - 1, 1);}for (int i = 0; i < b; i++) {gao.add_Edge(B[i].x - 1, 0, B[i].x - 1, 1);gao.add_Edge(B[i].x - 1, 0, B[i].y - 1, 1);gao.add_Edge(B[i].y - 1, 0, B[i].x -1 , 1);gao.add_Edge(B[i].y - 1, 0, B[i].y - 1, 1);}for (int i = 0; i < n; i++) {for (int j = 0; j < i; j++) {if (g[i][j][3] > d)gao.add_Edge(i, 0, j, 1);if (g[i][j][2] > d)gao.add_Edge(i, 1, j, 0);if (g[i][j][1] > d)gao.add_Edge(i, 0, j, 0);if (g[i][j][0] > d)gao.add_Edge(i, 1, j, 1);}}return gao.solve();
}int main() {while (~scanf("%d%d%d", &n, &a, &b)) {s1.read(); s2.read();for (int i = 0; i < n; i++) {p[i].read();for (int j = 0; j < i; j++) {g[i][j][0] = dis(p[i], s1) + dis(p[j], s1);g[i][j][1] = dis(p[i], s2) + dis(p[j], s2);g[i][j][2] = dis(p[i], s1) + dis(p[j], s2) + dis(s1, s2);g[i][j][3] = dis(p[i], s2) + dis(p[j], s1) + dis(s1, s2);}}for (int i = 0; i < a; i++) A[i].read();for (int i = 0; i < b; i++) B[i].read();int l = 0, r = 7777777;if (!judge(r)) printf("-1\n");else {while (l < r) {int mid = (l + r) / 2;if (judge(mid)) r = mid;else l = mid + 1;}printf("%d\n", l);}}return 0;
}

版权声明:本文博主原创文章。博客,未经同意不得转载。

HDU 1815, POJ 2749 Building roads(2-sat)相关推荐

  1. POJ 2749 Building roads

    POJ_2749 一开始没有想到去二分距离,看了别人的报告之后恍然大悟. 这是一个2-SAT的问题,首先我们要去找到核心变量,可以看出每个牛的有着要么和S1相连,要么和S2相连的逻辑关系,因此可以把奶 ...

  2. [poj] 2749 building roads

    原题 2-SAT+二分答案! 最小的最大值,这肯定是二分答案.而我们要2-SATcheck是否在该情况下有可行解. 对于目前的答案limit,首先把爱和恨连边,然后我们n^2枚举每两个点通过判断距离来 ...

  3. POJ 2749 Building roads 2-sat+二分答案

    把爱恨和最大距离视为限制条件,可以知道,最大距离和限制条件多少具有单调性 所以可以二分最大距离,加边+check 1 #include<cstdio> 2 #include<algo ...

  4. HDU 1816, POJ 2723 Get Luffy Out(2-sat)

    HDU 1816, POJ 2723 Get Luffy Out 题目链接 题意:N串钥匙.每串2把,仅仅能选一把.然后有n个大门,每一个门有两个锁,开了一个就能通过,问选一些钥匙,最多能通过多少个门 ...

  5. POJ 1696 Space Ant(极角排序)【计算几何】

    ACM博客_kuangbin POJ 1696 Space Ant(极角排序) Space Ant Time Limit: 1000MS   Memory Limit: 10000K Total Su ...

  6. poj 2769 感觉♂良好 (单调栈)

    poj 2769 感觉♂良好 (单调栈) 比尔正在研发一种关于人类情感的新数学理论.他最近致力于研究一个日子的好坏,如何影响人们对某个时期的回忆. 比尔为人的一天赋予了一个正整数值. 比尔称这个值为当 ...

  7. POJ 3253 Fence Repair(修篱笆)

    POJ 3253 Fence Repair(修篱笆) Time Limit: 2000MS   Memory Limit: 65536K [Description] [题目描述] Farmer Joh ...

  8. 上交张伟楠副教授:基于模型的强化学习算法,基本原理以及前沿进展(附视频)

    2020 北京智源大会 本文属于2020北京智源大会嘉宾演讲的整理报道系列.北京智源大会是北京智源人工智能研究院主办的年度国际性人工智能高端学术交流活动,以国际性.权威性.专业性和前瞻性的" ...

  9. 在linux下的使用复制命令cp,不让出现“overwrite”(文件覆盖)提示的方法。

    2019独角兽企业重金招聘Python工程师标准>>> 在linux下的使用复制命令cp,不让出现"overwrite"(文件覆盖)提示的方法. 一般我们在使用c ...

最新文章

  1. 若依框架使用数据权限
  2. Linux C编程--进程间通信(IPC)5--System V IPC 机制3--共享内存
  3. OpenCV差分二值化的实时场景文本检测的实例(附完整代码)
  4. java创建一个人函数类_Java对象和类–学习如何创建和实现
  5. Python+Selenium+PIL+Tesseract真正自动识别验证码进行一键登录
  6. linux ip地址漂移,Linux 实现高可用性(HA) —之ip 漂移方法(vrrp)
  7. 【Node】—系统模块
  8. Node.js和io.js将合并到Node基金会下
  9. 微型计算机原理及应用技术ppt,微型计算机原理及应用技术.ppt
  10. c语言的get函数的用法,get函数的用法
  11. 2022年天津仁爱学院专升本化学工程与工艺专业对口专业限制范围
  12. 2022年施工升降机司机(建筑特殊工种)考题及答案
  13. 手机设备唤醒计算机,手机遥控电脑开机神器!局域网唤醒App
  14. 服务器复制文件出现io错误,win7系统复制文件时发生IO错误的解决方法
  15. 三年功能测试转型自动化测试,月薪涨到了25k,是怎么做到的?
  16. CVE-2020-15999:Chrome Freetype字体库堆溢出漏洞通告
  17. 天敏VC4000视频开发设计方案
  18. 数据库的多表连接查询 emp表,dept表,salgrade表
  19. 计算机课一学期做了什么总结,计算机课程总结范文精选 .doc
  20. 小程序分销商城能帮助商家解决哪些问题?

热门文章

  1. Beam概念学习系列之SDKs
  2. MySQL 基本应用 count() 与 group by
  3. 插入排序:直接插入排序希尔排序
  4. bootstrap学习5-栅格系统
  5. CODE[VS] 1346 HelloWorld编译器
  6. 使用javah生成.h文件, 出现无法访问android.app,Activity的错误的解决
  7. Sql Server数据库备份和恢复:原理篇
  8. ASP.NET2.0中控件的简单异步回调
  9. 诗与远方:无题(三十)- 凄凉缘空
  10. *** is required and cannot be removed from the server