首页 技术 正文
技术 2022年11月20日
0 收藏 733 点赞 3,720 浏览 2892 个字

嘟嘟嘟


最近把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;
}
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,918
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,444
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,255
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,069
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,701
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,741