hdu1815 2sat + 二分 + 建图
题意:
给你两个总部,s1 ,s2,和n个点,任意两点之间都是通过这个总部相连的,其中有一些点不能连在同一个总部上,有一些点可以连接在同一个总部上,总部和总部之间可以直接连接,就是假如a,b相连,可以使这样四中情况中的一种
a-s1 s1 - b
a-s2 s2 - b
a-s1 s1 - s2 s2 - b
a-s2 s2 - s1 s1 - b
最后问你任意ab距离最远的最近是多少。
思路:
首先这个题目的总部有两个,还有一些限制关系,那么很容易就想到2sat问题,关键是怎么建边,怎样找到限制关系,还是举例子说容易懂,
s_x1[i] : 表示i点到S1的距离。
s_x2[i] : 表示i点到S2的距离。
D 表示S1,S2的距离。
彼此厌恶 x -> ~y ,y -> ~x ,~y -> x ,~x -> y
彼此喜欢 x -> y ,~x -> ~y ,y -> x ,~y -> ~x
s_x1[x] + s_x1[y] > mid x -> ~y ,y -> ~x
s_x2[x] + s_x2[y] > mid ~x -> y ,~y -> x
s_x1[x] + s_x2[y] + D > mid x -> y ,~y -> ~x
s_x2[x] + s_x1[y] + D > mid ~x -> ~y ,y -> x
每次二分就这么建边就ok了,还有提示下,之前在网上看到有个人的题解是直接先跑了便彼此厌恶和喜欢的,然后二分的时候就不管那个了,那个我感觉正确性说不通,我是每次都全部从新建边的,上面的如果写错了请大家留言指教,互相学习。
#include<stdio.h>
#include<string.h>
#include<stack> #define N_node 1000 + 10
#define N_edge 5000000 + 300
using namespace std; typedef struct
{
int to ,next;
}STAR; typedef struct
{
int x ,y;
}NODE; STAR E1[N_edge] ,E2[N_edge];
NODE S1 ,S2 ,A;
int s_x1[550] ,s_x2[550];
int list1[N_node] ,list2[N_node] ,tot;
int Belong[N_node] ,cnt;
int mark[N_node];
int F[1100][2] ,NF[1100][2];
stack<int>st; void add(int a ,int b)
{
E1[++tot].to = b;
E1[tot].next = list1[a];
list1[a] = tot; E2[tot].to = a;
E2[tot].next = list2[b];
list2[b] = tot;
} void DFS1(int s)
{
mark[s] = 1;
for(int k = list1[s] ;k ;k = E1[k].next)
if(!mark[E1[k].to]) DFS1(E1[k].to);
st.push(s);
} void DFS2(int s)
{
mark[s] = 1;
Belong[s] = cnt;
for(int k = list2[s] ;k ;k = E2[k].next)
if(!mark[E2[k].to]) DFS2(E2[k].to);
} int abss(int x)
{
return x > 0 ? x : -x;
} int dis(NODE a ,NODE b)
{
return abss(a.x - b.x) + abss(a.y - b.y);
} bool ok(int mid ,int n ,int m ,int q)
{
memset(list1 ,0 ,sizeof(list1));
memset(list2 ,0 ,sizeof(list2));
tot = 1;
for(int i = 1 ;i <= m ;i ++)
{
int x = NF[i][0] * 2 ,xx = NF[i][0] * 2 + 1;
int y = NF[i][1] * 2 ,yy = NF[i][1] * 2 + 1;
add(x ,yy) ,add(y ,xx);
add(yy ,x) ,add(xx ,y);
}
for(int i = 1 ;i <= q ;i ++)
{
int x = F[i][0] * 2 ,xx = F[i][0] * 2 + 1;
int y = F[i][1] * 2 ,yy = F[i][1] * 2 + 1;
add(x ,y) ,add(xx ,yy);
add(y ,x) ,add(yy ,xx);
}
int D = dis(S1 ,S2);
for(int i = 0 ;i < n ;i ++)
for(int j = i + 1 ;j < n ;j ++)
{
int x = i * 2 ,xx = i * 2 + 1;
int y = j * 2 ,yy = j * 2 + 1;
if(s_x1[i] + s_x1[j] > mid) add(x ,yy) ,add(y ,xx);
if(s_x2[i] + s_x2[j] > mid) add(xx ,y) ,add(yy ,x);
if(s_x1[i] + s_x2[j] + D > mid) add(x ,y) ,add(yy ,xx);
if(s_x2[i] + s_x1[j] + D > mid) add(xx ,yy) ,add(y ,x);
}
memset(mark ,0 ,sizeof(mark));
while(!st.empty()) st.pop();
for(int i = 0 ;i < n * 2 ;i ++)
if(!mark[i]) DFS1(i);
memset(mark ,0 ,sizeof(mark));
cnt = 0;
while(!st.empty())
{
int xin = st.top();
st.pop();
if(mark[xin]) continue;
++ cnt;
DFS2(xin);
}
int mk = 0;
for(int i = 0 ;i < n * 2 && !mk;i += 2)
if(Belong[i] == Belong[i^1]) mk = 1;
return !mk;
} int main ()
{
int n ,m ,q;
int i ,low ,mid ,up;
while(~scanf("%d %d %d" ,&n ,&m ,&q))
{
scanf("%d %d %d %d" ,&S1.x ,&S1.y ,&S2.x ,&S2.y);
low = up = 8000000;
for(i = 0 ;i < n ;i ++)
{
scanf("%d %d" ,&A.x ,&A.y);
s_x1[i] = dis(A ,S1);
s_x2[i] = dis(A ,S2);
if(low > s_x1[i]) low = s_x1[i];
if(low > s_x2[i]) low = s_x2[i];
}
for(i = 1 ;i <= m ;i ++)
{
scanf("%d %d" ,&NF[i][0] ,&NF[i][1]);
NF[i][0] -- ,NF[i][1] --;
}
for(i = 1 ;i <= q ;i ++)
{
scanf("%d %d" ,&F[i][0] ,&F[i][1]);
F[i][0] -- ,F[i][1] -- ;
}
int ans = -1;
while(low <= up)
{
mid = (low + up) >> 1;
if(ok(mid ,n ,m ,q))
ans = mid ,up = mid - 1;
else low = mid + 1;
}
printf("%d\n" ,ans);
}
return 0;
}
hdu1815 2sat + 二分 + 建图的更多相关文章
- 关于2-sat的建图方法及解决方案
转载增减: https://blog.csdn.net/qq_24451605/article/details/47126143 https://blog.csdn.net/u012915516/ar ...
- P3355 骑士共存问题 二分建图 + 当前弧优化dinic
P3355 骑士共存问题 题意: 也是一个棋盘,规则是“马”不能相互打到. 思路: 奇偶点分开,二分图建图,这道题要注意每个点可以跑八个方向,两边都可以跑,所以边 = 20 * n * n. 然后di ...
- HDU1815 2-sat+二分
Building roads Time Limit: 10000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tot ...
- [poj 3678]Katu Pazzle[2-SAT常用建图法]
题意: 不说了..典型的2-SAT 常用模型: 重点: 突出"绑定性". 连线表示限制而非可行. 因为最后要求对立点不在同一强连通分量是说同一强连通中的点必须同时选. 坑: 首先是 ...
- hdu3715 二分+2sat+建图
题意: 给你一个递归公式,每多一层就多一个限制,问你最多能递归多少层. 思路: 先分析每一层的限制 x[a[i]] + x[b[i]] != c[i],这里面x[] = 0,1, ...
- 【ARC069F】Flags 2-sat+线段树优化建图+二分
Description 数轴上有 n 个旗子,第 ii 个可以插在坐标 xi或者 yi,最大化两两旗子之间的最小距离. Input 第一行一个整数 N. 接下来 N 行每行两个整数 xi, ...
- Codeforces 587D - Duff in Mafia(2-SAT+前后缀优化建图)
Codeforces 题面传送门 & 洛谷题面传送门 2-SAT hot tea. 首先一眼二分答案,我们二分答案 \(mid\),那么问题转化为,是否存在一个所有边权都 \(\le mid\ ...
- BZOJ-1822 Frozen Nova 冷冻波 计(jie)算(xi)几何+二分+最大流判定+经典建图
这道逼题!感受到了数学对我的深深恶意(#‵′).... 1822: [JSOI2010]Frozen Nova 冷冻波 Time Limit: 10 Sec Memory Limit: 64 MB S ...
- BZOJ-1305 dance跳舞 建图+最大流+二分判定
跟随YveH的脚步又做了道网络流...%%% 1305: [CQOI2009]dance跳舞 Time Limit: 5 Sec Memory Limit: 162 MB Submit: 2119 S ...
随机推荐
- POJ-3259(最短路+Bellman-Ford算法判负圈)
Wormholes POJ-3259 这题是最短路问题中判断是否存在负圈的模板题. 判断负圈的一个关键就是理解:如果在图中不存在从s可达的负圈,最短路径不会经过一个顶点两次.while循环最多执行v- ...
- Java 中为什么要设计包装类
尽人事,听天命.博主东南大学硕士在读,热爱健身和篮球,乐于分享技术相关的所见所得,关注公众号 @ 飞天小牛肉,第一时间获取文章更新,成长的路上我们一起进步 本文已收录于 「CS-Wiki」Gitee ...
- FreeBSD ibus输入法框架配置
FreeBSD ibus输入法框架配置 ibus输入法框架配置.xinitrc中增加XIM=ibus; export XIMGTK_IM_MODULE=ibus; export GTK_IM_MODU ...
- 设置beeline连接hive的数据展示格式
问题描述:beeline -u 方式导出数据,结果文件中含有"|"(竖杠). 执行的sql为:beeline -u jdbc:hive2://hadoop1:10000/defau ...
- MySQL数据库与python交互
1.安装引入模块 安装mysql模块 pip install PyMySQL; 文件中引入模块 import pymysql 2.认识Connection对象 用于建立与数据库的连接 创建对象:调用c ...
- 【DB宝46】NoSQL数据库之CouchBase简介、集群搭建、XDCR同步及备份恢复
目录 一. CouchBase概述 1.1.简述 1.2.CouchDB和CouchBase比对 1.2.1.CouchDB和CouchBase的相同之处 1.2.2.CouchDB和CouchBas ...
- Python异步asyncio快速实践模版
只是参考快速跑起来模版,细节或者封装流畅使用需要详细阅读aiohttp文档 1 import asyncio 2 3 async def foo(): 4 await print('bar') 5 6 ...
- Typora标题自动编号+设定快捷键技巧
Typora标题自动编号 提示:要了解将这些CSS片段放在哪里,请参阅添加自定义CSS. 打开Typora偏好设置,打开主题文件夹,在主题文件夹中创建base.user.css文件,放置以下内容,则T ...
- 敏捷史话(十三):我被 Facebook 解雇了——Kent Beck
2011年,Kent Beck 加入了 Facebook .那时候的他已年过半百,几十年的经验让他自认为非常了解软件行业.在 Facebook 的新手训练营期间,Kent 开始意识到,Facebook ...
- 第十届蓝桥杯大赛软件类省赛C/C++研究生组 试题I:灵能传输
在游戏<星际争霸 II>中,高阶圣堂武士作为星灵的重要 AOE 单位,在游戏的中后期发挥着重要的作用,其技能"灵能风暴"可以消耗大量的灵能对一片区域内的敌军造成毁灭性的 ...