HDU1815 2-sat+二分
Building roads |
Time Limit: 10000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) |
Total Submission(s): 30 Accepted Submission(s): 12 |
Problem Description
Farmer John's farm has N barns, and there are some cows that live in each barn. The cows like to drop around, so John wants to build some roads to connect these barns. If he builds roads for every pair of different barns, then he must build N * (N - 1) / 2 roads, which is so costly that cheapskate John will never do that, though that's the best choice for the cows.
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
The first line of input consists of 3 integers N, A and B (2 <= N <= 500, 0 <= A <= 1000, 0 <= B <= 1000), which are the number of barns, the number of pairs of barns in which the cows hate each other and the number of pairs of barns in which the cows are friends with each other.
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
You just need output a line containing a single integer, which represents the maximum of the distances between every pair of barns, if John selects the optimal road-building scheme. Note if there is no feasible solution, just output -1.
|
Sample Input
4 1 1 |
Sample Output
53246 |
Source
POJ Monthly - 2006.01.22 - zhucheng
|
题意:
有n个仓库,两个中转站s1,s2,要求每个农场要么和S1场地连接要么和S2场地连接,且每个农场之间的连接距离的最大值最小 ,有a对仓库不能连同一个中转站,b对仓库必须连同一个中转站。
代码:
/*
二分枚举最大距离L,判断一下每个农场可连接的场地(以下的连边表示,a表示和S1连接,!a表示和S2连接)
(前提是dis[a][s1/s2]<=L,dis[b][s1/s2]<=L......................)
如果dis[a][S1] + dis[b][S1] > L,那么表明a和b不能同时和S1连接,连边a -> !b, b->!a
如果dis[a][S2] + dis[b][S2] > L,那么表明a和b不能同时和S2连接,连边!a -> b, !b->a
如果dis[a][S1] + dis[b][S2] + dis[S1][S2] > L,那么表明a农场连接S1时,b农场不能连接S2。b农场连接S2时,a农场不能连接S1,连边 a->b, !b->!a
如果dis[a][S2] + dis[b][S1] + dis[S1][S2] > L,那么表明a农场连接S2时,b农场不能连接S1。b农场连接S1时,a农场不能连接S2,连边 !a->!b, b->a 接下来还要处理A中不可连接限制和B种连接限制.
注意:二分范围如果小了会wa的。
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
using namespace std;
const int maxn=;
int dis[][],x[],y[],likx[],liky[],hatx[],haty[];
/********************** 2-sat模板 **********************/
struct Twosat{
int n;
vector<int> g[maxn*];
bool mark[maxn*];
int s[maxn*],c;
bool dfs(int x){
if(mark[x^]) return false;
if(mark[x]) return true;
mark[x]=true;
s[c++]=x;
for(int i=;i<(int)g[x].size();i++)
if(!dfs(g[x][i])) return false;
return true;
}
void init(int n){
this->n=n;
for(int i=;i<n*;i++) g[i].clear();
memset(mark,,sizeof(mark));
}
void add_clause(int x,int xval,int y,int yval){//这个函数随题意变化
x=x*+xval;
y=y*+yval;
g[x].push_back(y);
}
bool solve(){
for(int i=;i<n*;i+=)
if(!mark[i]&&!mark[i+]){
c=;
if(!dfs(i)){
while(c>) mark[s[--c]]=false;
if(!dfs(i+)) return false;
}
}
return true;
}
};
/*********************** 2-sat模板 ************************/
int main(){
int n,A,B,a,b;
Twosat solver;
while(~scanf("%d%d%d",&n,&A,&B)){
scanf("%d%d%d%d",&x[n],&y[n],&x[n+],&y[n+]);
for(int i=;i<n;i++){
scanf("%d%d",&x[i],&y[i]);
dis[i][n]=dis[n][i]=(fabs(x[i]-x[n])+fabs(y[i]-y[n]));
dis[i][n+]=dis[n+][i]=(fabs(x[i]-x[n+])+fabs(y[i]-y[n+]));
} dis[n][n+]=dis[n+][n]=(fabs(x[n]-x[n+])+fabs(y[n]-y[n+]));
for(int i=;i<A;i++){
scanf("%d%d",&a,&b);
a--;b--;
hatx[i]=a;haty[i]=b;
}
for(int i=;i<B;i++){
scanf("%d%d",&a,&b);
a--;b--;
likx[i]=a;liky[i]=b;
}
int L=,R=,M,ans=-;
while(L<=R){
M=(L+R)/;
solver.init(n);
for(int i=;i<A;i++){
solver.add_clause(hatx[i],,haty[i],);
solver.add_clause(hatx[i],,haty[i],);
solver.add_clause(haty[i],,hatx[i],);
solver.add_clause(haty[i],,hatx[i],);
}
for(int i=;i<B;i++){
solver.add_clause(likx[i],,liky[i],);
solver.add_clause(likx[i],,liky[i],);
solver.add_clause(liky[i],,likx[i],);
solver.add_clause(liky[i],,likx[i],);
}
for(int i=;i<n;i++){
//if(dis[i][n]>M) solver.add_clause(i,0,i,1);
//if(dis[i][n+1]>M) solver.add_clause(i,1,i,0);
for(int j=i+;j<n;j++){
if(dis[i][n]<=M&&dis[j][n]<=M&&dis[i][n]+dis[j][n]>M){
solver.add_clause(i,,j,);
solver.add_clause(j,,i,);
}
if(dis[i][n+]<=M&&dis[j][n+]<=M&&dis[i][n+]+dis[j][n+]>M){
solver.add_clause(i,,j,);
solver.add_clause(j,,i,);
}
if(dis[i][n]<=M&&dis[j][n+]<=M&&dis[i][n]+dis[j][n+]+dis[n][n+]>M){
solver.add_clause(i,,j,);
solver.add_clause(j,,j,);
}
if(dis[i][n+]<=M&&dis[j][n]<=M&&dis[i][n+]+dis[j][n]+dis[n][n+]>M){
solver.add_clause(i,,j,);
solver.add_clause(j,,i,);
}
}
}
if(solver.solve()) {R=M-;ans=M;}
else L=M+;
}
printf("%d\n",ans);
}
return ;
}
HDU1815 2-sat+二分的更多相关文章
- HDU1815(二分+2-SAT)
Building roads Time Limit: 10000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- 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,必需选相 ...
随机推荐
- Python3 Tkinter-Pack
1.创建 from tkinter import * root=Tk() print(root.pack_slaves()) Label(root,text='pack').pack() print( ...
- HDU 1569 方格取数(2)(最大流最小割の最大权独立集)
Description 给你一个m*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取数所在的2个格子不能相邻,并且取出的数的和最大. ...
- 【转】AMD 的 CommonJS wrapping
其实本文的标题应该是「为什么我不推荐使用 AMD 的 Simplified CommonJS wrapping」,但太长了不好看,为了美观我只能砍掉一截. 它是什么? 为了复用已有的 CommonJS ...
- 自测之Lesson6:文件I/O
题目:区分文件I/O和标准I/O. 区别: ①首先两者一个显著的不同点在于,标准I/O默认采用了缓冲机制,比如调用fopen函数,不仅打开一个文件,而且建立了一个缓冲区(读写模式下将建立两个缓冲区), ...
- c++SDK c#调用_疑难杂症
在编写过程中,会不时遇到各种问题: 1.dll明显在和exe同一目录下但调用不成功, 2.运行正常,没有报错,参数数值运行过程中也一致,但结果就是达不到预想, 都是dll没有引用完全造成的影响. 推荐 ...
- HDU 5816 Hearthstone 概率dp
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5816 Hearthstone Time Limit: 2000/1000 MS (Java/Othe ...
- 关于GenericJDBCException的问题
在spring和hibernate整合的初步阶段,还没有编辑hibernate.cfg.xml这个文件,只有一个beans.xml文件.此时遇到了一个bug. Exception in thread ...
- TCP系列03—连接管理—2、TCP连接的同时打开和同时关闭
在前面的内容中我们介绍了TCP连接管理中最常见的三次握手方式和四次挥手的方式.但是有可能A和B两端同时执行主动打开并连接对方或者同时执行主动关闭连接(尽管发生这种情况的可能性比较低低),这个时候的流程 ...
- 3dContactPointAnnotationTool开发日志(二二)
昨天是实现了显示GameObject子GameObject的选项卡功能,今天就是要让statusPanel可以控制它们的位置.旋转和缩放了. 没什么难的,对应选项卡绑定上对应的物体或子物体即可 ...
- Python中编码问题:u'\xe6\x97\xa0\xe5\x90\x8d' 类型和 ‘\u559c\u6b22\u4e00\u4e2a\u4eba ’ 转为utf-8的解决办法
相信小伙伴们遇到过类似这样的问题,python2中各种头疼的转码,类似u'\xe6\x97\xa0\xe5\x90\x8d' 的编码,直接s.decode()是无法解决编码问题.尝试了无数办法,都无法 ...