hdu 1815 2-SAT经典题
来源:互联网 发布:佛山seo外包 编辑:程序博客网 时间:2024/05/29 13:22
题意:
n个农场要连在转接站上 共有两个转接站s1,s2
每个农场可以选择连在s1或者s2上
给出m条限制关系:两个牧场必须连在同一个转接站上 或者 两个必须连在不同的转接站上~
然后给出转接站之间的距离 牧场和转接站之间的距离
问 在满足限制条件的前提下 怎样连接可以使得任意两个牧场之间的联通之后的距离的最大值最小~
思路:
最大值最小 —> 阔以想到二分求解
选一或者选二两个选择 + 二元的限制关系 —>阔以想到2-SAT
二分枚举最大值,然后根据枚举的最大值,判断每一条边可不可以加进去 然后再进一步增加二元限制关系
#include <cstdio>#include <cstring>#include <cstdlib>#include <vector>#include <algorithm>#include <cmath>using namespace std;const int maxn = 10005;const int maxm = 200005;struct Edge{ int to, next;}edge[maxm];int head[maxn], tot;void init(){ tot = 0; memset(head, -1, sizeof(head));}void add_Edge_(int u, int v){ edge[tot].to = v; edge[tot].next = head[u]; head[u] = tot++;}bool vis[maxn];int S[maxn], top;bool dfs(int u){ if(vis[u^1]) return false; if(vis[u]) return true; vis[u] = true; S[top++] = u; for(int i = head[u]; i != -1; i = edge[i].next){ int v = edge[i].to; if(!dfs(v)) return false; } return true;}bool Twosat(int n){ memset(vis, false, sizeof(vis)); for(int i = 0; i < n; i += 2){ if(vis[i] || vis[i^1]) continue; top = 0; if(!dfs(i)){ while(top) vis[S[--top]] = false; if(!dfs(i^1)) return false; } } return true;}const int N = 505;int n, a, b;struct Point { int x, y; void read() { scanf("%d%d", &x, &y); }} s1, s2, p[N], A[N * 2], B[N * 2];int dis(Point a, Point b) { int dx = a.x - b.x; int dy = a.y - b.y; return abs(dx) + abs(dy);}int g[N][N][4];bool judge(int d) { init(); for (int i = 0; i < a; i++) { int u = A[i].x-1, v = A[i].y-1; add_Edge_(u*2, v*2+1); add_Edge_(v*2, u*2+1); add_Edge_(u*2+1, v*2); add_Edge_(v*2+1, u*2); } for (int i = 0; i < b; i++) { int u = B[i].x-1, v = B[i].y-1; add_Edge_(u*2, v*2); add_Edge_(v*2, u*2); add_Edge_(u*2+1, v*2+1); add_Edge_(v*2+1, u*2+1); } for (int i = 0; i < n; i++) { for (int j = 0; j < i; j++) { if (g[i][j][3] > d){ add_Edge_(i*2+1, j*2+1); add_Edge_(j*2, i*2); } if (g[i][j][2] > d){ add_Edge_(i*2, j*2); add_Edge_(j*2+1, i*2+1); } if (g[i][j][1] > d){ add_Edge_(i*2+1, j*2); add_Edge_(j*2+1, i*2); } if (g[i][j][0] > d){ add_Edge_(i*2, j*2+1); add_Edge_(j*2, i*2+1); } } } return Twosat(n*2);}int main() { while (~scanf("%d%d%d", &n, &a, &b)) { s1.read(); s2.read(); for (int i = 0; i < n; i++) { p[i].read(); for (int j = 0; j < i; j++) { g[i][j][0] = dis(p[i], s1) + dis(p[j], s1); g[i][j][1] = dis(p[i], s2) + dis(p[j], s2); g[i][j][2] = dis(p[i], s1) + dis(p[j], s2) + dis(s1, s2); g[i][j][3] = dis(p[i], s2) + dis(p[j], s1) + dis(s1, s2); } } for (int i = 0; i < a; i++) A[i].read(); for (int i = 0; i < b; i++) B[i].read(); int l = 0, r = 7777777; if (!judge(r)) printf("-1\n"); else { while (l < r) { int mid = (l + r) / 2; if (judge(mid)) r = mid; else l = mid + 1; } printf("%d\n", r); } } return 0;}
0 0
- hdu 1815 2-SAT经典题
- hdu 1824 && hdU 3062 2-SAT经典
- hdu 3622 2-sat经典问题
- hdu 1815(二分+2-sat)
- HDU - 1815 Building roads (2-SAT)
- 2-SAT+二分——HDU 1815
- HDU 3062 Party 2-SAT 入门题
- HDU 3062 Party(2-SAT简单题)
- hdu 4421 2-sat 好题
- HDU 3062 Party(2-SAT简单题)
- 2-SAT好题hdu-3622
- HDU 3062 Party. (2-SAT简单题)
- HDU 3715 2-sat
- hdu 3062 2-SAT
- HDU 4421 2-SAT
- hdu 3062 (2-SAT)
- hdu 1824 (2-SAT)
- hdu 1824 2-sat
- 深入理解java虚拟机【并发编程缓存】
- STL—list
- 问题解决——maven出现“Dynamic Web Module 3.0 requires Java 1.6 or newer.”错误
- 跨域的解决方案
- 关于Andriod studio的报错问题
- hdu 1815 2-SAT经典题
- 采用全文索引解决模糊查询速度慢的问题
- 软件工程概念
- 移动webapp前端开发小结
- leetcode Intersection of Two Linked Lists
- 数组循环位移 三种
- fbd2fbs过采样转换的问题
- TQ2440 学习笔记—— 9、嵌入式编程基础知识【arm-linux-gcc 选项】
- eclipse从数据库逆向生成Hibernate实体类