POJ2749 Building roads
嘟嘟嘟
最近把21天漏的给不上。
今天重温了一下2-SAT,感觉很简单。就是把所有条件都转化成如果……必然能导出……。然后就这样连边建图,这样一个强连通分量中的所有点必然都是真或者假。从而根据这个点拆点后的两个点是否在一个强连通分量里判断是否有解。
这题人很容易想到拆点:\(i\)表示\(i\)连向\(s_1\),\(i + n\)表示\(i\)连向\(s_2\)。
这道题关键在于距离这个限制。我们肯定能想到二分,但是接下来我就没想出来,因为2-SAT的图的边权是没有意义的。但实际上这个也是可以用2-SAT的思路解决的:比如\(dis(i, s_1) + dis(j, s_1) > mid\),那么就说明,如果\(i\)连了\(s_1\),\(j\)只能连\(s_2\),因此我们连边\((i, j + n)\)。按照这种思路把四种情况都写一遍就行了。
这题和板子还有一个区别就是,板子给的条件形如"如果\(i\)为真,则\(j\)为假",也就是说,每一点的真假已知。但这到题真假不定,所以都得讨论。也就是说,对于每一个讨厌和喜欢关系,都得连4条边。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define In inline
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-8;
const int maxn = 5e2 + 5;
const int maxe = 5e6 + 5;
inline ll read()
{
  ll ans = 0;
  char ch = getchar(), last = ' ';
  while(!isdigit(ch)) last = ch, ch = getchar();
  while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
  if(last == '-') ans = -ans;
  return ans;
}
inline void write(ll x)
{
  if(x < 0) x = -x, putchar('-');
  if(x >= 10) write(x / 10);
  putchar(x % 10 + '0');
}
int n, A, B;
struct Node
{
  int x, y;
  friend In int dis(Node& A, Node& B)
  {
    return abs(A.x - B.x) + abs(A.y - B.y);
  }
}s[2], p[maxn], a[maxn << 1], b[maxn << 1];
int d[maxn << 1], DIS;
struct Edge
{
  int nxt, to;
}e[maxe];
int head[maxn << 1], ecnt = -1;
In void addEdge(int x, int y)
{
  e[++ecnt] = (Edge){head[x], y};
  head[x] = ecnt;
}
In void build(int x)
{
  for(int i = 1; i <= A; ++i)
    {
      int u = a[i].x, v = a[i].y;
      addEdge(u, v + n), addEdge(v, u + n);
      addEdge(u + n, v), addEdge(v + n, u);
    }
  for(int i = 1; i <= B; ++i)
    {
      int u = b[i].x, v = b[i].y;
      addEdge(u, v), addEdge(u + n, v + n);
      addEdge(v, u), addEdge(v + n, u + n);
    }
  for(int i = 1; i <= n; ++i)
    for(int j = 1; j <= n; ++j)
      if(i ^ j)
	{
	  if(d[i] + d[j] > x)
	    addEdge(i, j + n), addEdge(j, i + n);
	  if(d[i + n] + d[j + n] > x)
	    addEdge(i + n, j), addEdge(j + n, i);
	  if(d[i] + d[j + n] + DIS > x)
	    addEdge(i, j), addEdge(j + n, i + n);
	  if(d[i + n] + d[j] + DIS > x)
	    addEdge(i + n, j + n), addEdge(j, i);
	}
}
bool in[maxn << 1];
int dfn[maxn << 1], low[maxn << 1], cnt = 0;
int st[maxn << 1], top = 0, col[maxn << 1], ccol = 0;
In void dfs(int now)
{
  dfn[now] = low[now] = ++cnt;
  st[++top] = now; in[now] = 1;
  for(int i = head[now], v; ~i; i = e[i].nxt)
    {
      if(!dfn[v = e[i].to])
	{
	  dfs(v);
	  low[now] = min(low[now], low[v]);
	}
      else if(in[v]) low[now] = min(low[now], dfn[v]);
    }
  if(low[now] == dfn[now])
    {
      int x; ++ccol;
      do
	{
	  x = st[top--]; in[x] = 0;
	  col[x] = ccol;
	}while(x ^ now);
    }
}
In void init()
{
  ecnt = -1;
  for(int i = 1; i <= (n << 1); ++i)
    dfn[i] = low[i] = col[i] = in[i] = 0, head[i] = -1;
  cnt = top = ccol = 0;
}
In bool sat(int x)
{
  init();
  build(x);
  for(int i = 1; i <= (n << 1); ++i) if(!dfn[i]) dfs(i);
  for(int i = 1; i <= n; ++i)
    if(col[i] == col[i + n]) return 0;
  return 1;
}
int main()
{
  n = read(), A = read(), B = read();
  s[0].x = read(), s[0].y = read(), s[1].x = read(), s[1].y = read();
  for(int i = 1; i <= n; ++i) p[i].x = read(), p[i].y = read();
  for(int i = 1; i <= A; ++i) a[i].x = read(), a[i].y = read();
  for(int i = 1; i <= B; ++i) b[i].x = read(), b[i].y = read();
  DIS = dis(s[0], s[1]);
  for(int i = 1; i <= n; ++i) d[i] = dis(p[i], s[0]), d[i + n] = dis(p[i], s[1]);
  int L = 0, R = 6e6;
  while(L < R)
    {
      int mid = (L + R) >> 1;
      if(sat(mid)) R = mid;
      else L = mid + 1;
    }
  write(L == 6e6 ? -1 : L), enter;
  return 0;
}
												
											POJ2749 Building roads的更多相关文章
- [POJ2749]Building roads(2-SAT)
		
Building roads Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 8153 Accepted: 2772 De ...
 - POJ2749 Building roads  【2-sat】
		
题目 Farmer John's farm has N barns, and there are some cows that live in each barn. The cows like to ...
 - poj 3625 Building Roads
		
题目连接 http://poj.org/problem?id=3625 Building Roads Description Farmer John had just acquired several ...
 - poj  2749  Building roads  (二分+拆点+2-sat)
		
Building roads Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 6229 Accepted: 2093 De ...
 - BZOJ 1626: [Usaco2007 Dec]Building Roads 修建道路( MST )
		
计算距离时平方爆了int结果就WA了一次...... ------------------------------------------------------------------------- ...
 - HDU 1815, POJ 2749 Building roads(2-sat)
		
HDU 1815, POJ 2749 Building roads pid=1815" target="_blank" style="">题目链 ...
 - Building roads
		
Building roads Time Limit: 10000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tot ...
 - bzoj1626 / P2872 [USACO07DEC]道路建设Building Roads
		
P2872 [USACO07DEC]道路建设Building Roads kruskal求最小生成树. #include<iostream> #include<cstdio> ...
 - bzoj 1626: [Usaco2007 Dec]Building Roads 修建道路  -- 最小生成树
		
1626: [Usaco2007 Dec]Building Roads 修建道路 Time Limit: 5 Sec Memory Limit: 64 MB Description Farmer J ...
 
随机推荐
- js 数据类型具体分析
			
复习 点运算符 xxx.sss xxx是对象 sss是属性和方法.任何数据类型都是拥有属性和方法的.字符串 String var st=“hello world”.字符串的定义 ...
 - angular 分页插件的使用
			
html: <pagination total-items="totalItems" ng-model="currentPage" items-per-p ...
 - 在 ELK Docker 容器中查看,删除索引
			
使用 Docker 搭建好 ELK ( https://www.cnblogs.com/klvchen/p/9268510.html ) 环境后,如需查看 elasticsearch 的索引可采取以下 ...
 - 洛谷P4302 [SCOI2003]字符串折叠(区间dp)
			
题意 题目链接 Sol 裸的区间dp. 转移的时候枚举一下断点.然后判断一下区间内的字符串是否循环即可 `cpp #include<bits/stdc++.h> #define Pair ...
 - 洛谷P4462 [CQOI2018]异或序列(莫队)
			
题意 题目链接 Sol 一开始以为K每次都是给出的想了半天不会做. 然而发现读错题了维护个前缀异或和然后直接莫队搞就行,. #include<bits/stdc++.h> #define ...
 - vue.js及项目实战[笔记]— 03 vue.js插件
			
一. vue补充 1. 获取DOM元素 救命稻草,document.querySelector 在template中标示元素`ref = "xxx" 在要获取的时候,this.$r ...
 - 【vue】使用vue构建多页面应用
			
先了解一些单页面和多页面的区别 mm 多页应用模式MPA 单页应用模式SPA 应用构成 由多个完整页面构成 一个外壳页面和多个页面片段构成 跳转方式 页面之间的跳转是从一个页面跳转到另一个页面 页面片 ...
 - iOS ----------  获取设备的各种信息
			
一.目录结构: 获取屏幕宽度与高度 获取设备版本号 获取iPhone名称 获取app版本号 获取电池电量 获取当前系统名称 获取当前系统版本号 获取通用的唯一识别码UUID 获取当前设备IP 获取总内 ...
 - Flutter 布局(四)- Baseline、FractionallySizedBox、IntrinsicHeight、IntrinsicWidth详解
			
本文主要介绍Flutter布局中的Baseline.FractionallySizedBox.IntrinsicHeight.IntrinsicWidth四种控件,详细介绍了其布局行为以及使用场景,并 ...
 - Linux 之父自传《just for fun》读书笔记
			
一次偶然的机会,看到了阮一峰老师关于这本书的介绍,当时我就觉得这本书相当有趣. 在没有读这本书之前,我觉得 linus 作为发明 Linux 系统的人,应该是一个比较严肃的人,就像我的老师一样.但事实 ...