http://poj.org/problem?id=2749

(这个约翰的奶牛真多事…………………………)

i表示u与s1连,i+n表示u与s2连。

老规矩,u到v表示取u必须取v。

那么对于互相打架的奶牛u,v,有:

add(u,v+n);add(v,u+n);

add(u+n,v);add(v+n,u);

对于互为朋友的奶牛u,v,有:

add(u,v);add(v,u);

add(u+n,v+n);add(v+n,u+n);

但这远远不够,我们需要求最大值最小……

二分?但是我们怎么边处理矛盾边的距离?

那么我们也想把连边处理成冲突。

对于奶牛i,j,sxy表示i到x到y到j的距离,mid是我们二分的最大值最小。

那么显然,对于s>mid,那么一定是矛盾的,此时明显我们要采取相反的方法。

因为我们i和j的循环方式都是1-n,所以我们使i不变,把j变一下即可。

用代码表示就是:

if(s11>mid)add(i,j+n);
if(s12>mid)add(i,j);
if(s21>mid)add(i+n,j+n);
if(s22>mid)add(i+n,j);

(然而我还是查了题解的……我真菜)

#include<stack>
#include<cstdio>
#include<cstring>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
inline int read(){
int x=,w=;char ch=;
while(ch<''||ch>''){if(ch=='-')w=-;ch=getchar();}
while(ch>=''&&ch<=''){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*w;
}
const int N=;
const int M=;
struct cow{
int x;
int y;
}e[N],s[];
struct node{
int to;
int nxt;
}edge[M];
struct wzh{
int u;
int v;
}aa[],bb[];
int head[N*],dfn[N*],low[N*],to[N*];
int t,l,cnt;
bool instack[N*];
stack<int>q;
inline void add(int u,int v){
cnt++;
edge[cnt].to=v;
edge[cnt].nxt=head[u];
head[u]=cnt;
return;
}
void tarjan(int u){
t++;
dfn[u]=t;
low[u]=t;
q.push(u);
instack[u]=;
for(int i=head[u];i!=;i=edge[i].nxt){
int v=edge[i].to;
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
}else if(instack[v]){
low[u]=min(low[u],dfn[v]);
}
}
if(low[u]==dfn[u]){
int v;
l++;
do{
v=q.top();
q.pop();
instack[v]=;
to[v]=l;
}while(v!=u);
}
return;
}
inline int dis(int a,int k1,int k2,int b){
return
abs(s[k1].x-e[a].x)+abs(s[k1].y-e[a].y)+
abs(s[k1].x-s[k2].x)+abs(s[k1].y-s[k2].y)+
abs(s[k2].x-e[b].x)+abs(s[k2].y-e[b].y);
}
inline void clr(){
cnt=;l=;t=;
memset(head,,sizeof(head));
memset(dfn,,sizeof(dfn));
return;
}
int n,ans=-;
int a,b;
void erfen(int l,int r){
if(l>r)return;
clr();
int mid=(l+r)>>;
for(int i=;i<=a;i++){
int u=aa[i].u;int v=aa[i].v;
add(u,v+n);add(v,u+n);
add(u+n,v);add(v+n,u);
}
for(int i=;i<=b;i++){
int u=bb[i].u;int v=bb[i].v;
add(u,v);add(v,u);
add(u+n,v+n);add(v+n,u+n);
}
for(int i=;i<=n;i++){
for(int j=;j<=n;j++){
if(i==j)continue;
int s11=dis(i,,,j),s12=dis(i,,,j),
s21=dis(i,,,j),s22=dis(i,,,j);
if(s11>mid)add(i,j+n);
if(s12>mid)add(i,j);
if(s21>mid)add(i+n,j+n);
if(s22>mid)add(i+n,j);
}
}
for(int i=;i<=n*;i++){
if(!dfn[i])tarjan(i);
}
for(int i=;i<=n;i++){
if(to[i]==to[i+n]){
erfen(mid+,r);
return;
}
}
ans=mid;
erfen(l,mid-);
return;
}
//i表示与s1连,i+n表示与s2连
int main(){
n=read();a=read();b=read();
s[].x=read();s[].y=read();s[].x=read();s[].y=read();
for(int i=;i<=n;i++){
e[i].x=read();
e[i].y=read();
}
for(int i=;i<=a;i++){
aa[i].u=read();
aa[i].v=read();
}
for(int i=;i<=b;i++){
bb[i].u=read();
bb[i].v=read();
}
erfen(,);
printf("%d\n",ans);
return ;
}

POJ2749:Building roads——题解的更多相关文章

  1. [POJ2749]Building roads(2-SAT)

    Building roads Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8153   Accepted: 2772 De ...

  2. 洛谷 P2872 [USACO07DEC]道路建设Building Roads 题解

    P2872 [USACO07DEC]道路建设Building Roads 题目描述 Farmer John had just acquired several new farms! He wants ...

  3. 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 ...

  4. POJ2749 Building roads

    嘟嘟嘟 最近把21天漏的给不上. 今天重温了一下2-SAT,感觉很简单.就是把所有条件都转化成如果--必然能导出--.然后就这样连边建图,这样一个强连通分量中的所有点必然都是真或者假.从而根据这个点拆 ...

  5. USACO Building Roads

    洛谷 P2872 [USACO07DEC]道路建设Building Roads 洛谷传送门 JDOJ 2546: USACO 2007 Dec Silver 2.Building Roads JDOJ ...

  6. poj 3625 Building Roads

    题目连接 http://poj.org/problem?id=3625 Building Roads Description Farmer John had just acquired several ...

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

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

  8. BZOJ 1626: [Usaco2007 Dec]Building Roads 修建道路( MST )

    计算距离时平方爆了int结果就WA了一次...... ------------------------------------------------------------------------- ...

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

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

随机推荐

  1. 网易七鱼 Android 高性能日志写入方案

    本文来自网易云社区 作者:网易七鱼 Android 开发团队 前言 网易七鱼作为一款企业级智能客服系统,对于系统稳定性要求很高,不过难保用户在使用中不会出现问题,而 Android SDK 安装在用户 ...

  2. 问题:Visual Studio 2017 无法推送到github:The requested URL returned error: 403

    问题: Visual Studio 2017 无法推送到github:The requested URL returned error: 403 原因分析: Visual Studio 2017记录的 ...

  3. Linux命令应用大词典-第10章 Shell相关命令

    10.1 commond:抑制正常的Shell函数查找 10.2 exec:使用执行命令替换当前的shell进程 10.3 bash:GNU的Bourne-Again Shell解释器 10.4 bu ...

  4. [CF19B]Checkout Assistant

    题目描述 Bob 来到一家现购自运商店,将 n 件商品放入了他的手推车,然后到收银台 付款.每件商品由它的价格 pi 和收银员扫描它的时间 ti 秒定义.当收银员正在扫 描某件商品时,Bob 可以从他 ...

  5. Zookeeper与Eureka的区别

    Zookeeper与Eureka的区别 想要了解Zk与eureka的区别首先要知道CAP定理 CAP定理 Mysql强一致性(数据唯一出处),设计数据库设计的三范式 (表必须有主键:表不能有重复的列: ...

  6. 373. Partition Array by Odd and Even【LintCode java】

    Description Partition an integers array into odd number first and even number second. Example Given  ...

  7. MySql优化浅析

    优化点:合理的使用索引,可以大幅度提升sql查询效率,特别查询的表的数据量大的时候,效果明显.一.引言 公司的产品XX出行上线正式运营,随着数据量的变大,司机2000+,日订单1万+,注册乘客26W+ ...

  8. lock+Condition

    关键字 synchronized+wait/notify/notifyAll可以实现等待/通知模式,类ReentrantLock可以实现同样的功能,但需要借助Condition对象.Condition ...

  9. Python最长连续数列的O(n)解法

    题目 输入一个乱序的连续数列,输出其中最长连续数列长度,要求算法复杂度为 O(n) . 输入样例 100,4,200,1,3,2 54,55,300,12 1 5,4,3,2,1 1,2,3,4,5, ...

  10. HDU 4169 Wealthy Family(树形DP)

    Problem Description While studying the history of royal families, you want to know how wealthy each ...