HDU 1815, POJ 2749 Building roads(2-sat)
HDU 1815, POJ 2749 Building roads
pid=1815" target="_blank" style="">题目链接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)的更多相关文章
- poj 2749 Building roads (二分+拆点+2-sat)
Building roads Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 6229 Accepted: 2093 De ...
- poj 3625 Building Roads(最小生成树,二维坐标,基础)
题目 //最小生成树,只是变成二维的了 #define _CRT_SECURE_NO_WARNINGS #include<stdlib.h> #include<stdio.h> ...
- [poj] 2749 building roads
原题 2-SAT+二分答案! 最小的最大值,这肯定是二分答案.而我们要2-SATcheck是否在该情况下有可行解. 对于目前的答案limit,首先把爱和恨连边,然后我们n^2枚举每两个点通过判断距离来 ...
- POJ 2749 Building roads 2-sat+二分答案
把爱恨和最大距离视为限制条件,可以知道,最大距离和限制条件多少具有单调性 所以可以二分最大距离,加边+check #include<cstdio> #include<algorith ...
- HDU1815 Building roads(二分+2-SAT)
Problem Description Farmer John's farm has N barns, and there are some cows that live in each barn. ...
- POJ 1947 Rebuilding Roads (树形DP)
题意:给一棵树,在树中删除一些边,使得有一个连通块刚好为p个节点,问最少需要删除多少条边? 思路: 因为任一条边都可能需要被删除,独立出来的具有p个节点的连通块可能在任意一处地方.先从根开始DFS,然 ...
- POJ 1947 Rebuilding Roads(树形DP)
题目链接 题意 : 给你一棵树,问你至少断掉几条边能够得到有p个点的子树. 思路 : dp[i][j]代表的是以i为根的子树有j个节点.dp[u][i] = dp[u][j]+dp[son][i-j] ...
- POJ 3678 Katu Puzzle(2 - SAT) - from lanshui_Yang
Description Katu Puzzle is presented as a directed graph G(V, E) with each edge e(a, b) labeled by a ...
- HDU 1816, POJ 2723 Get Luffy Out(2-sat)
HDU 1816, POJ 2723 Get Luffy Out pid=1816" target="_blank" style="">题目链接 ...
随机推荐
- Git详解之六 Git工具(转)
Git 工具 现在,你已经学习了管理或者维护 Git 仓库,实现代码控制所需的大多数日常命令和工作流程.你已经完成了跟踪和提交文件的基本任务,并且发挥了暂存区和轻量级的特性分支及合并的威力. 接下来你 ...
- spring-security3.2.5实现中国式安全管理(转)
最近公司要做开发平台,对安全要求比较高:SPRING SECURTIY框架刚好对所有安全问题都有涉及,框架的作者最近还做了spring-session项目实现分布式会话管理,还有他的另一个开源项目sp ...
- Graphical Shell with WebShell - WebOS Internals
Graphical Shell with WebShell - WebOS Internals Graphical Shell with WebShell From WebOS Internals J ...
- Android 调用谷歌语音识别
調用谷歌语音识别其实很简单,直接利用 intent 跳转到手机里面的谷歌搜索 代码也很简单,直接调用方法 startVoiceRecognitionActivity() 如果大家手机里面没有谷歌搜索, ...
- Invalid character constant
Invalid character constant 无效的字符常数 可能是双引号写成了单引号了.
- Android 从相冊获取近期拍摄的多张照片(获取相机拍照所存储的照片)
转载请标明出处:http://blog.csdn.net/android_ls/article/details/39928519 在做公司项目时.遇到的需求:自己定义显示照片的网格视图,显示用户近期採 ...
- hdu4115 Eliminate the Conflict
Eliminate the Conflict Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- osx下快捷键相应符号
2张图展示mac下相应的按键符号: 很多其它文章请前往小胖轩.
- AJAX基础知识点学�
1.AJAX(Asynchronous JavaScript and XML)即,异步JavaScript和XML 2.同步/异步差别 同步: ①每次进行整个页面的刷新 ②同步的链接在同一时间仅仅能有 ...
- B桥接模式ridge
1.一个简短的引论 1)模式概述:将抽象部分与实现部分分离.使它们都能够独立的变化.让抽象类和派生类各自实现自己的对象.当一个系统有多维度的变化时,将各个维度分离出来让它们独立于变化(多角度地分类实现 ...