HDU1815(二分+2-SAT)
Building roads
Time Limit: 10000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1569 Accepted Submission(s): 490
Problem Description
Clever John just had another good idea. He first builds two transferring point S1 and S2, and then builds a road connecting S1 and S2 and N roads connecting each barn with S1 or S2, namely every barn will connect with S1 or S2, but not both. So that every pair of barns will be connected by the roads. To make the cows don't spend too much time while dropping around, John wants to minimize the maximum of distances between every pair of barns.
That's not the whole story because there is another troublesome problem. The cows of some barns hate each other, and John can't connect their barns to the same transferring point. The cows of some barns are friends with each other, and John must connect their barns to the same transferring point. What a headache! Now John turns to you for help. Your task is to find a feasible optimal road-building scheme to make the maximum of distances between every pair of barns as short as possible, which means that you must decide which transferring point each barn should connect to.
We have known the coordinates of S1, S2 and the N barns, the pairs of barns in which the cows hate each other, and the pairs of barns in which the cows are friends with each other.
Note that John always builds roads vertically and horizontally, so the length of road between two places is their Manhattan distance. For example, saying two points with coordinates (x1, y1) and (x2, y2), the Manhattan distance between them is |x1 - x2| + |y1 - y2|.
Input
Next line contains 4 integer sx1, sy1, sx2, sy2, which are the coordinates of two different transferring point S1 and S2 respectively.
Each of the following N line contains two integer x and y. They are coordinates of the barns from the first barn to the last one.
Each of the following A lines contains two different integers i and j(1 <= i < j <= N), which represent the i-th and j-th barns in which the cows hate each other.
The same pair of barns never appears more than once.
Each of the following B lines contains two different integers i and j(1 <= i < j <= N), which represent the i-th and j-th barns in which the cows are friends with each other. The same pair of barns never appears more than once.
You should note that all the coordinates are in the range [-1000000, 1000000].
Output
Sample Input
12750 28546 15361 32055
6706 3887
10754 8166
12668 19380
15788 16059
3 4
2 3
Sample Output
Source
思路:二分枚举最大值limit,然后重新构图,用2-SAT判定可行性。用Xi表示第i个牛棚连到S1,~Xi表示连到S2,检查每一个约束条件,构图:
1.hate关系的i,j Xi->~Xj ~Xi->Xj Xj->~Xi ~Xj->Xi
2.friend关系的i,j Xi->Xj ~Xi->~Xj Xj->Xi ~Xj->~Xi
接下来的也要检查,因为引入参数,就是多了约束条件了
这四种情况就是i,j到达对方的所有情况了
3.dist(i,S1)+dist(S1,j)>limit Xi->~Xj Xj->Xi
4.dist(i,S2)+dist(S2,j)>limit ~Xi->Xj ~Xj->Xi
5.dist(i,S1)+dist(S1,S2)+dist(S2,j)>limit Xi->Xj ~Xj->~Xi
5.dist(i,S2)+dist(S2,S1)+dist(S1,j)>limit ~Xi->~Xj Xj->Xi
然后求强连通分量判断Xi与~Xi是否在同一个连通分量中,是的话就有矛盾。
//2017-08-28
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath> using namespace std; const int N = ;
const int M = N*N*;
int head[N], rhead[N], tot, rtot;
struct Edge{
int to, next;
}edge[M], redge[M]; void init(){
tot = ;
rtot = ;
memset(head, -, sizeof(head));
memset(rhead, -, sizeof(rhead));
} void add_edge(int u, int v){
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++; redge[rtot].to = u;
redge[rtot].next = rhead[v];
rhead[v] = rtot++;
} vector<int> vs;//后序遍历顺序的顶点列表
bool vis[N];
int cmp[N];//所属强连通分量的拓扑序 //input: u 顶点
//output: vs 后序遍历顺序的顶点列表
void dfs(int u){
vis[u] = true;
for(int i = head[u]; i != -; i = edge[i].next){
int v = edge[i].to;
if(!vis[v])
dfs(v);
}
vs.push_back(u);
} //input: u 顶点编号; k 拓扑序号
//output: cmp[] 强连通分量拓扑序
void rdfs(int u, int k){
vis[u] = true;
cmp[u] = k;
for(int i = rhead[u]; i != -; i = redge[i].next){
int v = redge[i].to;
if(!vis[v])
rdfs(v, k);
}
} //Strongly Connected Component 强连通分量
//input: n 顶点个数
//output: k 强连通分量数;
int scc(int n){
memset(vis, , sizeof(vis));
vs.clear();
for(int u = ; u < n; u++)
if(!vis[u])
dfs(u);
int k = ;
memset(vis, , sizeof(vis));
for(int i = vs.size()-; i >= ; i--)
if(!vis[vs[i]])
rdfs(vs[i], k++);
return k;
} int n, A, B, dis_s1[N], dis_s2[N], dis_s1_s2;
struct Point{
int x, y;
}point[N], s1, s2, hate[N], friends[N]; //input: 两个点
//output: 两点间距离
double distance(Point a, Point b){
return abs(a.x-b.x) + abs(a.y-b.y);
} bool check(int limit){
init();
// i 表示 i 连 s1, NOT i 表示 i 连 s2
for(int i = ; i < n; i++){
bool fg = true;
if(distance(point[i], s1) > limit){
add_edge(i, i+n);
fg = false;
}
if(distance(point[i], s2) > limit){
if(!fg)return false;
add_edge(i+n, i);
}
for(int j = i+; j < n; j++){
if(dis_s1[i] + dis_s1[j] > limit){
add_edge(i, j+n);// i -> s1, j -> s2
add_edge(j, i+n);// j -> s1, i -> s2
}
if(dis_s2[i] + dis_s2[j] > limit){
add_edge(i+n, j);// i -> s2, j -> s1
add_edge(j+n, i);// j -> s2, i -> s1
}
if(dis_s1[i] + dis_s1_s2 + dis_s2[j] > limit){
add_edge(i, j);// i -> s1, j -> s1
add_edge(j+n, i+n);// j -> s2, i -> s2
}
if(dis_s2[i] + dis_s1_s2 + dis_s1[j] > limit){
add_edge(i+n, j+n);// i -> s2, j -> s2
add_edge(j, i);// j -> s1, i -> s1
}
}
}
for(int i = ; i < A; i++){
int u = hate[i].x, v = hate[i].y;
add_edge(u, v+n);
add_edge(v+n, u);
add_edge(v, u+n);
add_edge(u+n, v);
}
for(int i = ; i < B; i++){
int u = friends[i].x, v = friends[i].y;
add_edge(u, v);
add_edge(v, u);
add_edge(u+n, v+n);
add_edge(v+n, u+n);
}
scc(*n);
for(int i = ; i < n; i++){
if(cmp[i] == cmp[i+n])
return false;
}
return true;
} int main()
{
std::ios::sync_with_stdio(false);
//freopen("inputE.txt", "r", stdin);
while(cin>>n>>A>>B){
cin>>s1.x>>s1.y>>s2.x>>s2.y;
dis_s1_s2 = distance(s1, s2);
for(int i = ; i < n; i++){
cin>>point[i].x>>point[i].y;
dis_s1[i] = distance(point[i], s1);
dis_s2[i] = distance(point[i], s2);
}
for(int i = ; i < A; i++){
cin>>hate[i].x>>hate[i].y;
hate[i].x--;
hate[i].y--;
}
for(int i = ; i < B; i++){
cin>>friends[i].x>>friends[i].y;
friends[i].x--;
friends[i].y--;
}
//r 开小了HDU会TLE,ORZ。。。
int l = , r = , mid, ans = -;
while(l <= r){
mid = (l+r)/;
if(check(mid)){
ans = mid;
r = mid-;
}else l = mid+;
}
cout<<ans<<endl;
}
return ;
}
HDU1815(二分+2-SAT)的更多相关文章
- HDU1815 2-sat+二分
Building roads Time Limit: 10000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tot ...
- hdu1815 2sat + 二分 + 建图
题意: 给你两个总部,s1 ,s2,和n个点,任意两点之间都是通过这个总部相连的,其中有一些点不能连在同一个总部上,有一些点可以连接在同一个总部上,总部和总部之间可以直接连接,就是假如a, ...
- HDU1815 Building roads(二分+2-SAT)
Problem Description Farmer John's farm has N barns, and there are some cows that live in each barn. ...
- 证明与计算(3): 二分决策图(Binary Decision Diagram, BDD)
0x01 布尔代数(Boolean algebra) 大名鼎鼎鼎的stephen wolfram在2015年的时候写了一篇介绍George Boole的文章:George Boole: A 200-Y ...
- Map Labeler POJ - 2296(2 - sat 具体关系建边)
题意: 给出n个点 让求这n个点所能建成的正方形的最大边长,要求不覆盖,且这n个点在正方形上或下边的中点位置 解析: 当然是二分,但建图就有点还行..比较难想..行吧...我太垃圾... 2 - s ...
- LA 3211 飞机调度(2—SAT)
https://vjudge.net/problem/UVALive-3211 题意: 有n架飞机需要着陆,每架飞机都可以选择“早着陆”和“晚着陆”两种方式之一,且必须选择一种,第i架飞机的早着陆时间 ...
- UVALive - 3211 (2-SAT + 二分)
layout: post title: 训练指南 UVALive - 3211 (2-SAT + 二分) author: "luowentaoaa" catalog: true m ...
- hdu3715 2-sat+二分
Go Deeper 题意:确定一个0/1数组(size:n)使得满足最多的条件数.条件在数组a,b,c给出. 吐槽:哎,一水提,还搞了很久!关键是抽象出题目模型(如上的一句话).以后做二sat:有哪些 ...
- POJ 2749 2SAT判定+二分
题意:图上n个点,使每个点都与俩个中转点的其中一个相连(二选一,典型2-sat),并使任意两点最大 距离最小(最大最小,2分答案),有些点相互hata,不能选同一个中转点,有些点相互LOVE,必需选相 ...
随机推荐
- sax解析xml,验证格式并支持自定义标签
一.sax简介 SAX是事件驱动型的XML解析方式.顺序读取XML文件,生成事件,传播到用户定义的回调方法中来处理XML文件. 优点: 分段处理xml,而不是将整个xml一次加载进内存,内存占用少,速 ...
- iOS-自定义NavigationItem返回按钮【pop返回按钮】
在用navigationVC时,返回按钮有时候不想用系统的,这里用继承的方式把按钮替换了,同时也可以实现系统的右滑返回,很简单: 1.创建基类 BasePopViewController 创建一个用于 ...
- (转)Python3之shutil模块
原文:https://www.cnblogs.com/wang-yc/p/5625046.html 一. 简介 shutil 是高级的文件,文件夹,压缩包处理模块. 二. 使用 shutil.copy ...
- (转)pathlib路径库使用详解
原文:https://xin053.github.io/2016/07/03/pathlib%E8%B7%AF%E5%BE%84%E5%BA%93%E4%BD%BF%E7%94%A8%E8%AF%A6 ...
- NIO基础之同步、异步、阻塞、非阻塞
这里区分几个概念,也是常见但是容易混淆的概念,就是标题中的同步.异步.阻塞.非阻塞. 一.同步与异步 同步与异步,关心的是消息通信的机制.也就是调用者和被调用者之间,消息是如何进行通知的.如果是调用者 ...
- hadoop2.7的目录结构
1.$HADOOP_HOME/bin目录下文件及作用 文件名称 说明 hadoop 用于执行hadoop脚本命令,被hadoop-daemon.sh调用执行,也可以单独执行,一切命令的核心 2.$HA ...
- 深入理解Spring的ImportSelector接口
ImportSelector接口是至spring中导入外部配置的核心接口,在SpringBoot的自动化配置和@EnableXXX(功能性注解)都有它的存在,关于SpringBoot的分析可以参考:深 ...
- Mysql大数据表优化处理
原文链接: https://segmentfault.com/a/1190000006158186 当MySQL单表记录数过大时,增删改查性能都会急剧下降,可以参考以下步骤来优化: 单表优化 除非单表 ...
- 数据库设计 Step by Step (1)——扬帆启航
引言:一直在从事数据库开发和设计工作,也看了一些书籍,算是略有心得.很久之前就想针 对关系数据库设计进行整理.总结,但因为种种原因迟迟没有动手,主要还是惰性使然.今天也算是痛下决心开始这项卓绝又令我兴 ...
- 使用vue3.0和element实现后台管理模板
通过自己所学的这段时间,利用空余时间,使用vue3.0脚手架搭建的一个关于后台的管理模板,所实现功能也是模仿一个后台的界面,数据分为两种存放,一种是直接存储到mlab,这里的数据是存放这登录注册,只有 ...