POJ 2749 Building roads
POJ_2749
一开始没有想到去二分距离,看了别人的报告之后恍然大悟。
这是一个2-SAT的问题,首先我们要去找到核心变量,可以看出每个牛的有着要么和S1相连,要么和S2相连的逻辑关系,因此可以把奶牛看做核心变量,并用2*i表示第i个奶牛和S1相连,用2*i+1表示和S2相连。
首先,我们要喜爱和憎恨的关系转化成边。如果i和j相互憎恨,那么如果i连S1,那么j必然连S2,如果i连S2,那么j必然连S1,反过来也是一样的。于是我们需要连4条边,分别是i->~j、~i->j、j->~i、~j->i。对于喜爱的关系,同理也需要连4条边,分别是i->j、~i->~j、j->i、~j->~i。
其次,我们需要找到两两之间最大距离的最小值。我们可以采用二分枚举的方式求解,设二分的距离值为mid,S1与S2的距离值为D,奶牛与S1的距离为dis1[],奶牛与S2的距离为dis2[],我们可以得到下列限制条件,并将其转化成边:
①如果dis1[i]+dis1[j]>mid,即i和j不能同时和S1相连,于是我们可以得到2条边,i->~j、j->~i。
②如果dis2[i]+dis2[j]>mid,即i和j不能同时和S2相连,于是我们又可以得到2两边,~i->j、~j->i。
③如果dis1[i]+D+dis2[j]>mid,即不能出现这种情况:i与S1相连,同时j与S2相连,于是有i->j、~j->~i。
④如果dis2[i]+D+dis1[j]>mid,即不能出现这种情况:i与S2相连,同时j与S1相连,于是有~i->~j、j->i。
如果没有一种可行的方案,需要输出-1。
#include<stdio.h>#include<string.h>#include<stdlib.h>#define MAXN 1500#define MAXM 3000000#define INF 12000000int A, B, N, D, sx1, sy1, sx2, sy2, x[MAXN], y[MAXN];int first[MAXN], next[MAXM], v[MAXM], e, dis[2][MAXN];int dfn[MAXN], low[MAXN], cnt, s[MAXN], top, ins[MAXN];int color[MAXN], col;int hate[2][MAXN], love[2][MAXN];void init(){int i; scanf("%d%d%d%d", &sx1, &sy1, &sx2, &sy2); D = abs(sx1 - sx2) + abs(sy1 - sy2);for(i = 0; i < N; i ++) { scanf("%d%d", &x[i], &y[i]); dis[0][i] = abs(x[i] - sx1) + abs(y[i] - sy1); dis[1][i] = abs(x[i] - sx2) + abs(y[i] - sy2); }for(i = 0; i < A; i ++) { scanf("%d%d", &hate[0][i], &hate[1][i]); hate[0][i] --; hate[1][i] --; }for(i = 0; i < B; i ++) { scanf("%d%d", &love[0][i], &love[1][i]); love[0][i] --; love[1][i] --; }}void add_edge(int i, int j){ v[e] = j; next[e] = first[i]; first[i] = e; e ++;}void build(int mid){int i, j, k; e = 0; memset(first, -1, sizeof(first));for(i = 0; i < A; i++) { add_edge(2 * hate[0][i], 2 * hate[1][i] + 1); add_edge(2 * hate[0][i] + 1, 2 * hate[1][i]); add_edge(2 * hate[1][i], 2 * hate[0][i] + 1); add_edge(2 * hate[1][i] + 1, 2 * hate[0][i]); }for(i = 0; i < B; i++) { add_edge(2 * love[0][i], 2 * love[1][i]); add_edge(2 * love[0][i] + 1, 2 * love[1][i] + 1); add_edge(2 * love[1][i], 2 * love[0][i]); add_edge(2 * love[1][i] + 1, 2 * love[0][i] + 1); }for(i = 0; i < N; i ++)for(j = i + 1; j < N; j ++) {if(dis[0][i] + dis[0][j] > mid) { add_edge(2 * i, 2 * j + 1); add_edge(2 * j, 2 * i + 1); }if(dis[1][i] + dis[1][j] > mid) { add_edge(2 * i + 1, 2 * j); add_edge(2 * j + 1, 2 * i); }if(dis[0][i] + D + dis[1][j] > mid) { add_edge(2 * i, 2 * j); add_edge(2 * j + 1, 2 * i + 1); }if(dis[1][i] + D + dis[0][j] > mid) { add_edge(2 * i + 1, 2 * j + 1); add_edge(2 * j, 2 * i); } }}void tarjan(int u){int i; dfn[u] = low[u] = ++ cnt;for(i = first[u]; i != -1; i = next[i]) {if(!dfn[v[i]]) { s[top ++] = v[i]; ins[v[i]] = 1; tarjan(v[i]);if(low[v[i]] < low[u]) low[u] = low[v[i]]; }else if(ins[v[i]] && dfn[v[i]] < low[u]) low[u] = dfn[v[i]]; }if(low[u] == dfn[u]) {for(s[top] = -1; s[top] != u;) { top --; ins[s[top]] = 0; color[s[top]] = col; } col ++; }}int com(int mid){int i, j; build(mid); cnt = top = col = 0; memset(dfn, 0, sizeof(dfn)); memset(ins, 0, sizeof(ins));for(i = 0 ; i < 2 * N; i ++)if(!dfn[i]) { s[top ++] = i; ins[i] = 1; tarjan(i); }for(i = 0; i < 2 * N; i ++)if(color[i] == color[i ^ 1])return 0;return 1;}int main(){int i, j, k, mid, max, min;while(scanf("%d%d%d", &N, &A, &B) == 3) { init(); max = INF + 1; min = -1;for(;;) { mid = (max + min + 1) / 2;if(mid == max)break;if(com(mid)) max = mid;else min = mid; } printf("%d\n", max > INF ? -1 : max); }return 0; }
POJ 2749 Building roads相关推荐
- HDU 1815, POJ 2749 Building roads(2-sat)
HDU 1815, POJ 2749 Building roads 题目链接HDU 题目链接POJ 题意: 有n个牛棚, 还有两个中转站S1和S2, S1和S2用一条路连接起来. 为了使得随意牛棚两个 ...
- POJ 2749 Building roads 2-sat+二分答案
把爱恨和最大距离视为限制条件,可以知道,最大距离和限制条件多少具有单调性 所以可以二分最大距离,加边+check 1 #include<cstdio> 2 #include<algo ...
- [poj] 2749 building roads
原题 2-SAT+二分答案! 最小的最大值,这肯定是二分答案.而我们要2-SATcheck是否在该情况下有可行解. 对于目前的答案limit,首先把爱和恨连边,然后我们n^2枚举每两个点通过判断距离来 ...
- USACO07DEC道路建设Building Roads(prim算法+堆优化与Kruskal+路径压缩对比)
目录 primprimprim算法 KruskalKruskalKruskal算法 P2872 [USACO07DEC]道路建设Building Roads 4 1 1 1 3 1 2 3 4 3 1 ...
- 洛谷——P2872 [USACO07DEC]道路建设Building Roads
P2872 [USACO07DEC]道路建设Building Roads 题目描述 Farmer John had just acquired several new farms! He wants ...
- [BZOJ1626][Usaco2007 Dec]Building Roads 修建道路
1626: [Usaco2007 Dec]Building Roads 修建道路 Time Limit: 5 Sec Memory Limit: 64 MB Submit: 1730 Solved ...
- bzoj 1626: [Usaco2007 Dec]Building Roads 修建道路(最小生成树)
1626: [Usaco2007 Dec]Building Roads 修建道路 Time Limit: 5 Sec Memory Limit: 64 MB Submit: 1709 Solved ...
- 【POJ 1788 --- Building a New Depot】
[POJ 1788 --- Building a New Depot] Description Advanced Cargo Movement, Ltd. is successfully expand ...
- 【POJ - 1724 】ROADS (带限制的最短路 或 dfs 或 A*算法,双权值)
题干: N cities named with numbers 1 ... N are connected with one-way roads. Each road has two paramete ...
最新文章
- 北京决心一试:如何打造中国的HHMI和贝尔实验室?
- Qt + VS 【如何添加图片资源】
- 最新综述:用于组合优化的强化学习
- 分组交换中的时延、丢失和吞吐量
- javascript --- 属性描述符
- JavaFX:创建Sprite动画
- mysql 表ful,你所不知的table is full那些事
- C99标准的新特性(相对于Ansi C)
- csp是什么比赛_CSP-J/S认证 NOIP、NOI信息学竞赛解读!
- STM32F10X的IAP编程详解——开发指南
- 十道解分式方程及答案_解分式方程的题出20道还要带答案
- 折腾安装archlinx记录
- CollapsingToolbarLayout 标题字体及颜色设置
- 闹钟Android实验报告,定时闹钟我的实验报告.doc
- 内存不够的情况下python处理大规模数据
- 小学期项目(C语言)————外卖点餐系统(功能齐全)
- ( 纪中)1296. 城墙【暴力】
- 利尔达客思之“智能照明”的本质解析
- 损失函数里的from_logits=False是什么意思
- Nacos Spring Cloud入门