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 ...
随机推荐
- FakeTaobaoDeepLink - 复制淘宝deeplink来拦截淘宝广告的自动拉起
Fake Taobao Deeplink 复制 ** com.taobao.tao.welcome.Welcome ** 的intent-filter来拦截误触广告后自动拉起淘宝app 完整工程 Gi ...
- [源码分析] 消息队列 Kombu 之 启动过程
[源码分析] 消息队列 Kombu 之 启动过程 0x00 摘要 本系列我们介绍消息队列 Kombu.Kombu 的定位是一个兼容 AMQP 协议的消息队列抽象.通过本文,大家可以了解 Kombu 是 ...
- httpPost的两种方式
1,post-Body流和post参数,以下客户端代码和服务端代码可共用 客户端代码 /** * post 方法 * 抛送给EDI * @param url http://127.0.0.1:9003 ...
- 使用函数式语言实践DDD
长期以来我都在实践OOP,进而通过OOP来实现DDD,特别是如何通过面向对象的技巧来建立一个领域模型.OO的一些特性在建立领域模型时显得恰如其分,能否掌握OO的技巧,对创建领域模型有着至关重要的作用. ...
- 解决VM 与 Device/Credential Guard 不兼容(全网有效解决思路)
为什么要写这篇文章先说背景:前段时间因为学习Linux系统需要,自己本机用的是Windows系统,那这里就需要用到虚拟机来创建虚拟环境用来支持Linux系统 1: 于是乎,自己很激动的下载了vm虚拟机 ...
- Lzzy高级语言程序设计之while循环
public class Mq2 { public static void main(String[]args) { int b = 3; while (b < 7) { System.out. ...
- 总结数据科学家常用的Python库
概述 这篇文章中,我们挑选了24个用于数据科学的Python库. 这些库有着不同的数据科学功能,例如数据收集,数据清理,数据探索,建模等,接下来我们会分类介绍. 您觉得我们还应该包含哪些Python库 ...
- “/”应用程序中的服务器错误。||分析器错误消息: 未能加载类型“WebApplication1._Default”
环境VS2008 无法运行WEB项目,Winfrom程序OK. 新创建的WEB项目直接运行报下图错误. 尝试多种方法: 1,重新生成项目,运行.(失败) 2,重装VS2008(默认.完全.自定义)安装 ...
- Centos7安装以及设置Redis详细步骤
一.Redis安装: 1.指定文件夹下下载redis安装包: [root@bogon ~]# mkdir /usr/local/soft/redis [root@bogon ~]# cd /usr/l ...
- 抗DDOS应急预案实践-生产环境总结-建议必看
一.首先摸清楚环境与资源 为DDoS应急预案提供支撑 所在的网络环境中,有多少条互联网出口?每一条带宽多少? 每一条互联网出口的运营商是否支持DDoS攻击清洗,我们是否购买,或可以紧急试用?当发生DD ...