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 + 二分 + 建图不错的题目相关推荐
- hdu3715 二分+2sat+建图
题意: 给你一个递归公式,每多一层就多一个限制,问你最多能递归多少层. 思路: 先分析每一层的限制 x[a[i]] + x[b[i]] != c[i],这里面x[] = 0,1, ...
- CF-1147D Palindrome XOR (建图划分等价类)
CF-1147D Palindrome XOR (建图划分等价类) 题目链接 题意 给一个长度为n的01串c(可能存在'?',表示可以为0或是1) 问多少个数对(a,b)满足: $ 1\le a &l ...
- POJ 3281 -- Dining(最大流,拆点建图)
题目链接 Description Cows are such finicky eaters. Each cow has a preference for certain foods and drink ...
- hdu4560 不错的建图,二分最大流
题意: 我是歌手 Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Total Subm ...
- 差分约束问题 ---- 2019ccpc哈尔滨A. Artful Paintings[二分+差分约束+建图剪枝]
题目链接 题目大意: 有N≤3e3N≤3e3N≤3e3个格子,你可以任意给每个格子染色,但是要满足M≤3e3M≤3e3M≤3e3限制条件,限制条件有两种类型: 区间[l,r][l,r][l,r]中被染 ...
- [ZJOI2010] 贪吃的老鼠(二分+差分+神仙建图网络流)
problem luogu-P2570 solution 卧槽网络流尼玛神题 首先这个最小延长时间 TTT ,套路地考虑二分,将问题转化为判定性问题. 其次 n,mn,mn,m 和奶酪存在时间 [l, ...
- P6378 [PA2010] Riddle(2-sat/前后缀优化建图)
P6378 [PA2010] Riddle n个点m条边的无向图,分为k个部分,从每个部分选择恰好一个关键点,使得每条边至少有一个端点是关键点. 首先有这么多的限制,实际上就是一个选或者不选的问题,每 ...
- 【HDOJ7058】Ink on paper(生成树,或二分答案建图+并查集联通性)
1003 Ink on paper 题意: 给出平面中的n个点,每个点每秒向外扩散0.5cm,求多少时间后所有点的点会连在一起,输出时间的平方. 思路: 其实是很简单的最小生成树板子,Kruskal或 ...
- hdu1814 Peaceful Commission 2-SAT建图入门
题面 The Public Peace Commission should be legislated in Parliament of The Democratic Republic of Byte ...
最新文章
- mybaties插件生成代码
- SqlServer中除了sql和bak你还可以使用mdf文件来进行数据库的添加和分离
- 基于ssm的水果商城系统项目总结
- Spring5.0 Kafka2.11
- window.open和window.showModalDialog用法
- 学习如何写PHP MVC框架(1) -- 路由
- 程序员如何快速消除自己的知识短板?
- android framework资源,Android 添加framework资源包
- Win2008 R2 VDI动手实验系列之六:远程桌面虚拟机配置
- 丅rust是什么意思_网红编程语言Rust到底是个什么鬼?
- When Work Becomes a Game
- (简单课设)前端小白刚做的一个简单的移动端项目的分享和总结
- 如何衡量客户满意度?选好方法是关键!
- 初识DataTable
- 【Unity XR】Unity开发OpenXR
- codewars打怪日记 Greed is Good JavaScript中数组用法和 哈希表的使用
- 某互联网银行 区块链技术暑假实习生在线笔试 回忆
- 思寒漫谈测试人职业发展
- 也看罗永浩的锤子手机
- Centos登录日志 last和lastb命令整理