题意:
      给你两个总部,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 + 二分 + 建图不错的题目相关推荐

  1. hdu3715 二分+2sat+建图

    题意:       给你一个递归公式,每多一层就多一个限制,问你最多能递归多少层. 思路:      先分析每一层的限制 x[a[i]] + x[b[i]] != c[i],这里面x[] = 0,1, ...

  2. CF-1147D Palindrome XOR (建图划分等价类)

    CF-1147D Palindrome XOR (建图划分等价类) 题目链接 题意 给一个长度为n的01串c(可能存在'?',表示可以为0或是1) 问多少个数对(a,b)满足: $ 1\le a &l ...

  3. POJ 3281 -- Dining(最大流,拆点建图)

    题目链接 Description Cows are such finicky eaters. Each cow has a preference for certain foods and drink ...

  4. hdu4560 不错的建图,二分最大流

    题意: 我是歌手 Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Total Subm ...

  5. 差分约束问题 ---- 2019ccpc哈尔滨A. Artful Paintings[二分+差分约束+建图剪枝]

    题目链接 题目大意: 有N≤3e3N≤3e3N≤3e3个格子,你可以任意给每个格子染色,但是要满足M≤3e3M≤3e3M≤3e3限制条件,限制条件有两种类型: 区间[l,r][l,r][l,r]中被染 ...

  6. [ZJOI2010] 贪吃的老鼠(二分+差分+神仙建图网络流)

    problem luogu-P2570 solution 卧槽网络流尼玛神题 首先这个最小延长时间 TTT ,套路地考虑二分,将问题转化为判定性问题. 其次 n,mn,mn,m 和奶酪存在时间 [l, ...

  7. P6378 [PA2010] Riddle(2-sat/前后缀优化建图)

    P6378 [PA2010] Riddle n个点m条边的无向图,分为k个部分,从每个部分选择恰好一个关键点,使得每条边至少有一个端点是关键点. 首先有这么多的限制,实际上就是一个选或者不选的问题,每 ...

  8. 【HDOJ7058】Ink on paper(生成树,或二分答案建图+并查集联通性)

    1003 Ink on paper 题意: 给出平面中的n个点,每个点每秒向外扩散0.5cm,求多少时间后所有点的点会连在一起,输出时间的平方. 思路: 其实是很简单的最小生成树板子,Kruskal或 ...

  9. hdu1814 Peaceful Commission 2-SAT建图入门

    题面 The Public Peace Commission should be legislated in Parliament of The Democratic Republic of Byte ...

最新文章

  1. mybaties插件生成代码
  2. SqlServer中除了sql和bak你还可以使用mdf文件来进行数据库的添加和分离
  3. 基于ssm的水果商城系统项目总结
  4. Spring5.0 Kafka2.11
  5. window.open和window.showModalDialog用法
  6. 学习如何写PHP MVC框架(1) -- 路由
  7. 程序员如何快速消除自己的知识短板?
  8. android framework资源,Android 添加framework资源包
  9. Win2008 R2 VDI动手实验系列之六:远程桌面虚拟机配置
  10. 丅rust是什么意思_网红编程语言Rust到底是个什么鬼?
  11. When Work Becomes a Game
  12. (简单课设)前端小白刚做的一个简单的移动端项目的分享和总结
  13. 如何衡量客户满意度?选好方法是关键!
  14. 初识DataTable
  15. 【Unity XR】Unity开发OpenXR
  16. codewars打怪日记 Greed is Good JavaScript中数组用法和 哈希表的使用
  17. 某互联网银行 区块链技术暑假实习生在线笔试 回忆
  18. 思寒漫谈测试人职业发展
  19. 也看罗永浩的锤子手机
  20. Centos登录日志 last和lastb命令整理

热门文章

  1. JavaScript基础学习3
  2. memcached的最佳实践方案(转)
  3. 从前端角度来看网页设计
  4. 手机版网页设计注意事项
  5. NodeList 和 HTMLCollection
  6. 在 Mac OSX 版的 LispBox 环境上安装配置 SBCL 详细过程
  7. DOS下操作注册表的部分命令
  8. [转载]秀脱linux实战笔记linux-kernel-3.0.3实战篇
  9. Python学习(四)数据结构 —— set frozenset
  10. iOS网络编程开发—HTTP协议