题意:John有n个牛棚,每个牛棚都住着一些牛,这些牛喜欢串门(drop around, 学到了。。。),所以John想要建几条路把他们连接起来。他选择的方法是建两个相连中转站,然后每个牛棚连接其中一个中转站就好啦。现在的问题是有一些牛相互憎恨,所以不能连同一个中转站,而又有一些牛相互喜欢,必须连同一个中转站(再次感叹,人不如牛。。),现在要你来建边,要求,任意两个牛棚的距离的最大距离最短。两点距离是指哈密顿距离。比如u, v连的是同一个中转站s1,距离就是dis(u,s1)+dis(v,s1) 如果连不同的中转站就是dis(u,s1)+dis(v,s2)+dis(u,v),题意真的好不清楚啊

输入就是每个牛棚的坐标的中转站的坐标,已经牛之间的憎恨和喜欢关系。

输出最小距离。不能输出-1。

题解:二分。。。然后符合要求的边建图,2-sat求解。建图时喜欢和讨厌都要建四条边,仔细读题。。。仔细建边。。。

//我真的想吐槽我以前用的输入挂啊,我特么从哪搞来的辣鸡读入。。。用一次错一次。。。。

这套题做的我心真累。。。没有特别难的。。。但是每一道都wa的想死。。。

  1. #include <algorithm>
  2. #include <iostream>
  3. #include <cstring>
  4. #include <string>
  5. #include <vector>
  6. #include <bitset>
  7. #include <cstdio>
  8. #include <queue>
  9. #include <stack>
  10. #include <cmath>
  11. #include <list>
  12. #include <map>
  13. #include <set>
  14. #define pk(x) printf("%d\n", x)
  15. using namespace std;
  16. #define PI acos(-1.0)
  17. #define EPS 1E-6
  18. #define clr(x,c) memset(x,c,sizeof(x))
  19. typedef long long ll;
  20. const int N = ;
  21. const int M = ;
  22. inline int Scan()
  23. {
  24. char ch = getchar();
  25. int data = ;
  26. while (ch < '' || ch > '') ch = getchar();
  27. do {
  28. data = data* + ch-'';
  29. ch = getchar();
  30. } while (ch >= '' && ch <= '');
  31. return data;
  32. }
  33. struct Edge {
  34. int from, to, next;
  35. } edge[M];
  36. int head[N];
  37. int cntE;
  38. void addedge(int u, int v) {
  39. edge[cntE].from = u; edge[cntE].to = v; edge[cntE].next = head[u]; head[u] = cntE++;
  40. }
  41.  
  42. int dfn[N], low[N], idx;
  43. int stk[N], top;
  44. int in[N];
  45. int kind[N], cnt;
  46.  
  47. void tarjan(int u)
  48. {
  49. dfn[u] = low[u] = ++idx;
  50. in[u] = true;
  51. stk[++top] = u;
  52. for (int i = head[u]; i != -; i = edge[i].next) {
  53. int v = edge[i].to;
  54. if (!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
  55. else if (in[v]) low[u] = min(low[u], dfn[v]);
  56. }
  57. if (low[u] == dfn[u]) {
  58. ++cnt;
  59. while () {
  60. int v = stk[top--]; kind[v] = cnt; in[v] = false;
  61. if (v == u) break;
  62. }
  63. }
  64. }
  65.  
  66. void init() {
  67. cntE = ;
  68. memset(head, -, sizeof head);
  69. memset(dfn, , sizeof dfn);
  70. memset(in, false, sizeof in);
  71. idx = top = cnt = ;
  72. }
  73.  
  74. int ax[N], ay[N];
  75. int bx[N], by[N];
  76. int dis1[N], dis2[N];
  77. int n, a, b;
  78. int dis;
  79.  
  80. int cal(int x1, int y1, int x2, int y2) {
  81. return abs(x1-x2) + abs(y1-y2);
  82. }
  83.  
  84. bool ok(int x) {
  85. init();
  86. for (int i = ; i <= n; ++i) {
  87. for (int j = i+; j <= n; ++j) {
  88. if (dis1[i] + dis1[j] > x) addedge(i, n+j), addedge(j, n+i);
  89. if (dis2[i] + dis2[j] > x) addedge(i+n, j), addedge(j+n, i);
  90. if (dis1[i] + dis2[j] + dis > x) addedge(i, j), addedge(j+n, i+n);
  91. if (dis2[i] + dis1[j] + dis > x) addedge(i+n, j+n), addedge(j, i);
  92. }
  93. }
  94. for (int i = ; i < a; ++i) {
  95. addedge(ax[i], ay[i] + n), addedge(ay[i] + n, ax[i]);
  96. addedge(ay[i], ax[i] + n), addedge(ax[i] + n, ay[i]);
  97. }
  98. for (int i = ; i < b; ++i) {
  99. addedge(bx[i], by[i]), addedge(by[i], bx[i]);
  100. addedge(bx[i] + n, by[i] + n), addedge(by[i] + n, bx[i] + n);
  101. }
  102.  
  103. for (int i = ; i <= *n; ++i) if (!dfn[i]) tarjan(i);
  104.  
  105. for (int i = ; i <= n; i++) if (kind[i] == kind[i + n]) return false;
  106. return true;
  107. }
  108.  
  109. int main() {
  110. int x1, y1, x2, y2;
  111. int x, y;
  112. while (~scanf("%d%d%d", &n, &a, &b)) {
  113. x1 = Scan(); y1 = Scan(); x2 = Scan(); y2 = Scan();
  114. dis = cal(x1, y1, x2, y2);
  115. int maxn = ;
  116. for (int i = ; i <= n; ++i) {
  117. x = Scan(); y = Scan();
  118. dis1[i] = cal(x, y, x1, y1);
  119. dis2[i] = cal(x, y, x2, y2);
  120. maxn = max(maxn, max(dis1[i], dis2[i]));
  121. }
  122. maxn = maxn * + dis;
  123. for (int i = ; i < a; ++i) ax[i] = Scan(), ay[i] = Scan();
  124. for (int i = ; i < b; ++i) bx[i] = Scan(), by[i] = Scan();
  125.  
  126. int l = , r = maxn;
  127. int ans = -;
  128. while (l <= r) {
  129. int mid = (l+r) >> ;
  130. if (ok(mid)) ans = mid, r = mid - ;
  131. else l = mid + ;
  132. }
  133. printf("%d\n", ans);
  134. }
  135. return ;
  136. }

POJ 2749--Building roads(2-SAT)的更多相关文章

  1. HDU 1815, POJ 2749 Building roads(2-sat)

    HDU 1815, POJ 2749 Building roads pid=1815" target="_blank" style="">题目链 ...

  2. poj 2749 Building roads (二分+拆点+2-sat)

    Building roads Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6229   Accepted: 2093 De ...

  3. poj 3625 Building Roads(最小生成树,二维坐标,基础)

    题目 //最小生成树,只是变成二维的了 #define _CRT_SECURE_NO_WARNINGS #include<stdlib.h> #include<stdio.h> ...

  4. POJ 3678 Katu Puzzle(2 - SAT) - from lanshui_Yang

    Description Katu Puzzle is presented as a directed graph G(V, E) with each edge e(a, b) labeled by a ...

  5. POJ 1947 Rebuilding Roads (树形DP)

    题意:给一棵树,在树中删除一些边,使得有一个连通块刚好为p个节点,问最少需要删除多少条边? 思路: 因为任一条边都可能需要被删除,独立出来的具有p个节点的连通块可能在任意一处地方.先从根开始DFS,然 ...

  6. HDU1815 Building roads(二分+2-SAT)

    Problem Description Farmer John's farm has N barns, and there are some cows that live in each barn. ...

  7. POJ 1947 Rebuilding Roads(树形DP)

    题目链接 题意 : 给你一棵树,问你至少断掉几条边能够得到有p个点的子树. 思路 : dp[i][j]代表的是以i为根的子树有j个节点.dp[u][i] = dp[u][j]+dp[son][i-j] ...

  8. [poj] 2749 building roads

    原题 2-SAT+二分答案! 最小的最大值,这肯定是二分答案.而我们要2-SATcheck是否在该情况下有可行解. 对于目前的答案limit,首先把爱和恨连边,然后我们n^2枚举每两个点通过判断距离来 ...

  9. POJ 2749 Building roads 2-sat+二分答案

    把爱恨和最大距离视为限制条件,可以知道,最大距离和限制条件多少具有单调性 所以可以二分最大距离,加边+check #include<cstdio> #include<algorith ...

  10. Java实现 POJ 2749 分解因数(计蒜客)

    POJ 2749 分解因数(计蒜客) Description 给出一个正整数a,要求分解成若干个正整数的乘积,即a = a1 * a2 * a3 * - * an,并且1 < a1 <= ...

随机推荐

  1. AlphaGo 已经战胜了李世石,而你还不知道什么是机器学习?

    谷歌人工智能 AlphaGo 与韩国棋手李世石 3 月 15 日进行了最后一场较量,最终比赛结果为 AlphaGo 4:1 胜李世石,人机围棋大战巅峰对决至此落幕.我不知道大家有没有被震撼到,反正我的 ...

  2. C/C++ 框架,类库,资源集合

    很棒的 C/C++ 框架,类库,资源集合. Awesome C/C++ Standard Libraries Frameworks Artificial Intelligence Asynchrono ...

  3. HDU1465+递推

    经典的信封装信问题 f[ n ]  = ( n-1 ) * ( f[ n-1 ]+f[ n-2 ] ) #include<stdio.h> #include<string.h> ...

  4. ???????????? no permissions

    1.一手鞋地址 google http://developer.android.com/tools/device.html 我处理的方法如下: 我的问题: android的版卡 在Ubuntu12.0 ...

  5. android dialog 原来dialog对话框也有自己的按键监听事件 onKeyDown方法

    探讨在一个activity中按menu键时弹出自己定义的dialog(自定义菜单对话框)时,再按一次手机的menu键发现这个自定义的dialog菜单并没有关闭,原来是这个dialog内部也有onKey ...

  6. PowerDesigner(五)-概念数据模型(CDM生成LDM,PDM和OOM)

    概念数据模型 概念数据模型(Conceptual Data Model,CDM):表达的是数据整体逻辑结构,该结构独立于任何软件和数据存储结构,即它只是系统分析人员,应用程序设计人员,维护人员和用户之 ...

  7. [itint5]棋盘漫步

    要注意dp[0][0]要初始化为1. int totalPath(vector<vector<bool> > &blocked) { int m = blocked.s ...

  8. 微信支付开发1 微信支付URL配置

    本文介绍微信支付申请时如何设置授权目录及URL. 一.选择支付类型 目前有两种支付类型 JS API网页支付 Native原生支付 如果没有特殊要求,两种都勾选. 二.支付授权目录 目前可以选择htt ...

  9. C3p0/元数据/内省-Bean/自定义查询封装类/查询/分页

    c3p0连接池(C3p0连接池,只有当用户获取连接时,才会包装Connection.) 第一步:导入c3p0 第二步:在classpath目录下,创建一个c3p0-config.xml 第三步:创建工 ...

  10. 不输入密码ssh直接登录阿里云Linux主机

    服务器环境:阿里云云服务器,Linux版本 - CentOS 客户端环境:Mac OSX Terminal 注意: 如果有3个账号都要无密码登录, 则3个账号都要这么操作 在Terminal中用ssh ...