题意:图上n个点,使每个点都与俩个中转点的其中一个相连(二选一,典型2-sat),并使任意两点最大

距离最小(最大最小,2分答案),有些点相互hata,不能选同一个中转点,有些点相互LOVE,必需选相同中转点

(显然是2sat条件)。

关键:每次二分枚举limit,按limit建图,需要注意的是每条逻辑语句对应两条边(相互对称,逻辑上互为假言易位),

如:必需连通一个点,逻辑语句俩条:a->b,b->a,对应各自假言易位式,4条边。

相信二sat不再是问题了。

#include<iostream>//1200ms/2000ms 1A
#include<queue>
#include<stack>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
struct point
{
int x,y;
};
vector<vector<int> >e(1050);
int n,a,b;point s1,s2; int maxdis=4000001;
point po[505]; point hate[1005]; point love[1005];
int absint(int x)
{
if(x<0)return -x;
return x;
}
int dis(point aa,point bb) //距离
{
return absint(aa.x-bb.x)+absint(aa.y-bb.y);
}
void build(int limit) //每次二分后建图
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) //注意不要加ELSE
{
if(i==j)continue;
if((dis(po[i],s1)+dis(po[j],s2)+dis(s1,s2))>limit) //无法到达了,
{
e[2*i-1].push_back(2*j-1);
e[2*j-2].push_back(2*i-2);
}
if((dis(po[i],s1)+dis(po[j],s1))>limit)
{
e[2*i-1].push_back(2*j-2);
e[2*j-1].push_back(2*i-2);
}
if((dis(po[i],s2)+dis(po[j],s2))>limit)
{
e[2*i-2].push_back(2*j-1);
e[2*j-2].push_back(2*i-1);
}
}
for(int i=0;i<a;i++) //相互憎恨的
{
e[hate[i].x*2-1].push_back(hate[i].y*2-2);
e[hate[i].y*2-1].push_back(hate[i].x*2-2);
e[hate[i].x*2-2].push_back(hate[i].y*2-1);
e[hate[i].y*2-2].push_back(hate[i].x*2-1);
}
for(int i=0;i<b;i++) //相互喜爱的
{
e[love[i].x*2-1].push_back(love[i].y*2-1);
e[love[i].y*2-2].push_back(love[i].x*2-2);
e[love[i].y*2-1].push_back(love[i].x*2-1);
e[love[i].x*2-2].push_back(love[i].y*2-2);
}
}
int vis[1050];int dfn[1050];int low[1050];bool instack[1050];int block[1050];
int times=0; stack<int>s; int num=0;
void tarjan(int u) //下边是2sat缩点判断可行
{
dfn[u]=low[u]=++times;
instack[u]=1;
s.push(u);
int len=e[u].size();
for(int i=0;i<len;i++)
{
int v=e[u][i];
if(!vis[v])
{
vis[v]=1;
tarjan(v);
if(low[u]>low[v])low[u]=low[v];
}
else if(instack[v]&&dfn[v]<low[u])
low[u]=dfn[v];
}
if(dfn[u]==low[u])
{
num++;
int cur;
do{
cur=s.top();s.pop();
instack[cur]=0;
block[cur]=num;
}while(cur!=u);
}
}
bool check(int limit)
{
for(int i=0;i<=2*n-1;i++)
{
e[i].clear();
block[i]=vis[i]=dfn[i]=low[i]=instack[i]=0;
}
num=times=0;
build(limit);
for(int i=0;i<=2*n-1;i++)
if(!vis[i])
{
vis[i]=1;
tarjan(i);
}
for(int i=0;i<=2*n-1;i+=2)
if(block[i]==block[i+1])
return 0;
return 1;
}
int main()
{
scanf("%d%d%d",&n,&a,&b);scanf("%d%d%d%d",&s1.x,&s1.y,&s2.x,&s2.y);
for(int i=1;i<=n;i++)
scanf("%d%d",&po[i].x,&po[i].y);
for(int i=0;i<a;i++)
scanf("%d%d",&hate[i].x,&hate[i].y);
for(int i=0;i<b;i++)
scanf("%d%d",&love[i].x,&love[i].y);
int right=maxdis,left=0,mid;
if(!check(maxdis)){printf("-1\n");return 0;}
while(right>left+1)
{
mid=(right+left)/2;
if(check(mid))
{
right=mid;
}
else
left=mid;
}
if(check(right-1))printf("%d\n",right-1);
else printf("%d\n",right);
return 0;
}

POJ 2749 2SAT判定+二分的更多相关文章

  1. poj 2749 2-SAT问题

    思路:首先将hate和friend建边求其次2-SAT问题,判断是否能有解,没解就输出-1,否则用二分枚举最大的长度,将两个barn的距离小于mid的看做是矛盾,然后建边,求2-SAT问题.找出最优解 ...

  2. poj 2723 二分+2-sat判定

    题意:给出n对钥匙,每对钥匙只能选其中一个,在给出每层门需要的两个钥匙,只要一个钥匙就能开门,问最多能到哪层. 思路:了解了2-SAT判定的问题之后主要就是建图的问题了,这里建图就是对于2*n个钥匙, ...

  3. HDU 1815, POJ 2749 Building roads(2-sat)

    HDU 1815, POJ 2749 Building roads pid=1815" target="_blank" style="">题目链 ...

  4. POJ 3111 K Best ( 二分 )

    题意 : 给出 N 个物品的价值和重量,然后要求选出 K 个物品使得选出来物品的单位重量价值最大,最后输出被选物品的编号. 分析 :  很容易去想先算出每个物品的单位价值然后升序排序取前 K 个,但是 ...

  5. POJ 3273 Monthly Expense二分查找[最小化最大值问题]

    POJ 3273 Monthly Expense二分查找(最大值最小化问题) 题目:Monthly Expense Description Farmer John is an astounding a ...

  6. Java实现 POJ 2749 分解因数(计蒜客)

    POJ 2749 分解因数(计蒜客) Description 给出一个正整数a,要求分解成若干个正整数的乘积,即a = a1 * a2 * a3 * - * an,并且1 < a1 <= ...

  7. poj 2749 Building roads (二分+拆点+2-sat)

    Building roads Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6229   Accepted: 2093 De ...

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

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

  9. ZOJ 3717 二分+2-sat判定。

    好久没有2-sat了,此题当复习之用,二分求最大值+2-sat判断可行,此题主要跪于题意:The results should be rounded to three decimal places. ...

随机推荐

  1. Android Activity生命周期的几个问题

      每一个Android开发者都应该知道,android系统有四个重要的基本组件,即Activity(活动).Service(服务).Broadcast Receive(广播接收器)和Content ...

  2. Openrisc的or1200

    1 什么是OpenRISC OpenRISC 是硬件开源社区opencores开发的RISC指令集处理器架构,包括32 bits 的Openrisc1000 和64 bitsOpenrisc 2000 ...

  3. SOE 第五章

    SEO第五章 本次课目标: 1.  掌握代码优化 2.  掌握内链优化 一.代码优化 1)<h>标签 代表网页的标题,总共6个级别(h1-h6) 外观上显示字体的大小的修改,其中<h ...

  4. Boxes And Balls(三叉哈夫曼编码)

    题目 原题链接:http://codeforces.com/problemset/problem/884/D 现有一堆小石子,要求按要求的数目分成N堆,分别为a1.a2....an.具体的,每次选一个 ...

  5. MySQL(C#的链接姿势)

    介绍 这篇随笔主要介绍MySQL的基础API的使用姿势 基本使用姿势: 第一步:登陆数据库 string connStr = "Database=start;datasource=127.0 ...

  6. 如何用纯 CSS 创作一个 3D 文字跑马灯特效

    效果预览 在线演示 按下右侧的"点击预览"按钮在当前页面预览,点击链接全屏预览. https://codepen.io/zhang-ou/pen/GdrrZq 可交互视频教程 此视 ...

  7. MySQL 优化 之 Copying to tmp table on disk

    项目中遇到了慢查询问题 Sql语句 SELECT sum(price) AS price, `member_id` FROM `crm_upload` GROUP BY member_id ORDER ...

  8. Python爬虫-爬取京东商品信息-按给定关键词

    目的:按给定关键词爬取京东商品信息,并保存至mongodb. 字段:title.url.store.store_url.item_id.price.comments_count.comments 工具 ...

  9. UVA - 10410 Tree Reconstruction (根据dfs序和bfs序恢复一颗树)

    题意: 分析: 这题一开始完全没有思路, 一直没有找出规律. 参考了http://www.cnblogs.com/Wade-/p/6358859.html 和 http://www.cnblogs.c ...

  10. Tomcat启动慢(运行shutdown.sh的时候报错)

    Using CATALINA_BASE: /usr/local/tomcatUsing CATALINA_HOME: /usr/local/tomcatUsing CATALINA_TMPDIR: / ...