思路:首先将hate和friend建边求其次2-SAT问题,判断是否能有解,没解就输出-1,否则用二分枚举最大的长度,将两个barn的距离小于mid的看做是矛盾,然后建边,求2-SAT问题。找出最优解。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>
#define Maxn 3010
#define Maxm 1000000
using namespace std;
int dfn[Maxn],low[Maxn],vi[Maxn],head[Maxn],e,n,m,lab,top,Stack[Maxn],num,id[Maxn],A,B,ss;
struct Edge{int u,v,next,l;
}edge[Maxm];
struct Point{int x,y;
}p[Maxn],s1,s2;
struct Match{int a,b;
}hate[Maxn],Friend[Maxn];
void init()
{int i,j;memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low));memset(head,-1,sizeof(head));memset(id,0,sizeof(id));memset(vi,0,sizeof(vi));e=lab=num=top=0;
}
void add(int u,int v)
{edge[e].u=u,edge[e].v=v,edge[e].next=head[u],head[u]=e++;
}
int Dis(Point a,Point b)
{return abs(a.x-b.x)+abs(a.y-b.y);
}
void Tarjan(int u)
{int i,j,v;dfn[u]=low[u]=++lab;Stack[top++]=u;vi[u]=1;for(i=head[u];i!=-1;i=edge[i].next){v=edge[i].v;if(!dfn[v]){Tarjan(v);low[u]=min(low[u],low[v]);}if(vi[v])low[u]=min(low[u],dfn[v]);}if(low[u]==dfn[u]){++num;do{i=Stack[--top];vi[i]=0;id[i]=num;}while(i!=u);}
}
void build(int mid)
{int i,j;init();for(i=1;i<=n;i++)for(j=1;j<=n;j++){if(j==i)continue;if(Dis(p[i],s1)+Dis(p[j],s1)>mid){add(i,j+n);add(j,i+n);}if(Dis(p[i],s2)+Dis(p[j],s2)>mid){add(i+n,j);add(j+n,i);}if(Dis(p[i],s1)+Dis(p[j],s2)+ss>mid){add(i,j);add(j+n,i+n);}if(Dis(p[i],s2)+Dis(p[j],s1)+ss>mid){add(j,i);add(i+n,j+n);}}for(i=1;i<=A;i++){add(hate[i].a,hate[i].b+n);add(hate[i].b,hate[i].a+n);add(hate[i].a+n,hate[i].b);add(hate[i].b+n,hate[i].a);}for(i=1;i<=B;i++){add(Friend[i].a,Friend[i].b);add(Friend[i].a+n,Friend[i].b+n);add(Friend[i].b,Friend[i].a);add(Friend[i].b+n,Friend[i].a+n);}
}
int cal()
{int i;for(i=1;i<=n*2;i++){if(!dfn[i])Tarjan(i);}for(i=1;i<=n;i++){if(id[i]==id[i+n])return 0;}return 1;
}
int solve()
{int i,j;for(i=1;i<=A;i++){add(hate[i].a,hate[i].b+n);add(hate[i].b,hate[i].a+n);add(hate[i].a+n,hate[i].b);add(hate[i].b+n,hate[i].a);}for(i=1;i<=B;i++){add(Friend[i].a,Friend[i].b);add(Friend[i].a+n,Friend[i].b+n);add(Friend[i].b,Friend[i].a);add(Friend[i].b+n,Friend[i].a+n);}if(!cal())return -1;int l,r,mid;l=0;r=4000010;while(l+1<r){mid=(l+r)>>1;build(mid);if(cal())r=mid;elsel=mid;}return r;
}
int main()
{int i,j,a,b,c;while(scanf("%d%d%d",&n,&A,&B)!=EOF){init();scanf("%d%d%d%d",&s1.x,&s1.y,&s2.x,&s2.y);for(i=1;i<=n;i++)scanf("%d%d",&p[i].x,&p[i].y);for(i=1;i<=A;i++)scanf("%d%d",&hate[i].a,&hate[i].b);for(i=1;i<=B;i++)scanf("%d%d",&Friend[i].a,&Friend[i].b);ss=Dis(s1,s2);printf("%d\n",solve());}return 0;
}

转载于:https://www.cnblogs.com/wangfang20/p/3220262.html

poj 2749 2-SAT问题相关推荐

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

    HDU 1815, POJ 2749 Building roads 题目链接HDU 题目链接POJ 题意: 有n个牛棚, 还有两个中转站S1和S2, S1和S2用一条路连接起来. 为了使得随意牛棚两个 ...

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

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

  3. POJ 2749 Building roads

    POJ_2749 一开始没有想到去二分距离,看了别人的报告之后恍然大悟. 这是一个2-SAT的问题,首先我们要去找到核心变量,可以看出每个牛的有着要么和S1相连,要么和S2相连的逻辑关系,因此可以把奶 ...

  4. [poj] 2749 building roads

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

  5. poj pku图论、网络流入门题总结、汇总

    poj pku图论.网络流入门题总结.汇总 分类: acm图论 2010-08-25 18:49 243人阅读 评论(0) 收藏 举报 网络算法networkgraphconstructioninte ...

  6. POJ 图论分类 + DP(较全 自己又加了点)

    DP -----------动态规划 状态压缩DP 2411 (棋盘规模较大)状态压缩DP+DFS+滚动数组 2664 (棋盘规模较小)直接递推即可(DP) 2506 (棋盘规模较小)直接递推即可(D ...

  7. 《挑战程序设计竞赛(第2版)》习题册攻略

    本项目来源于GitHub 链接: 项目GitHub链接 1 前言 项目为<挑战程序设计竞赛(第2版)>习题册攻略,已完结.可配合书籍或笔记,系统学习算法. 题量:约200道,代码注释内含详 ...

  8. [kuangbin]各种各样的题单

    [kuangbin]各种各样的题单 专题1 简单搜索 POJ 1321 POJ 2251 POJ 3278 POJ 3279 POJ 1426 POJ 3126 POJ 3087 POJ 3414 F ...

  9. (转)2-sat 专题

    [2-sat]专题- 2-sat是一个逻辑性很强的算法,但是其套路比较固定,所以不是很热,题目很少,但也不乏AC后让人大呼爽快的好题,下面放出两篇极品论文还有几道题目的题解以供交流-- 2-sat学习 ...

最新文章

  1. 第一次作业:阅读优秀博文谈感想
  2. linux 下mongo 基础配置
  3. build muduo网络库undefined reference to问题
  4. usb host控制devie进入suspend模式
  5. [渝粤教育] 西南科技大学 数控机床与编程 在线考试复习资料
  6. 本地仓库settings.xml中使用阿里的仓库
  7. LeetCode:每日一题(2020.4.14)
  8. Python中List,tuple,Dictionary之间的区别
  9. 局域网邮件服务器搭建地址薄更新,搭建局域网邮件服务器
  10. 接口交互时的URL带有日期格式的参数,注意拼装地址中的特殊符号(如空格等)
  11. Oracle 获取当前日期及日期格式
  12. linux创建2g文件,嵌入式 创建一个2G的空文件(Linux命令dd)
  13. cocos2d-x 2.2 CocoStudio动画和界面编辑器按钮控制以及场景编辑器使用
  14. 多目标狼群优化算法(MGWO)
  15. 树莓派的蓝牙通讯(bluez、gattlib)
  16. 高电平复位还是低电平复位?
  17. downwell什么意思_downwelling_downwelling是什么意思翻译
  18. java日志:一、JUL使用
  19. Java 微信二维码支付
  20. 自动定时发送邮件的方法 —— 定时执行专家V6.8

热门文章

  1. Linux添加文件命令
  2. java调用天气预报的webservice
  3. Requests 2.18.1文档
  4. C#怎么给新建的winform程序添加资源文件夹Resources
  5. sklearn中的正则化
  6. Tomcat源码解析五:Tomcat请求处理过程
  7. sfp光模块和sfp+高速线缆有什么区别?
  8. 使用Bootstrap制作导航栏
  9. Java3y文章目录导航
  10. 只显示隐藏文件 显示指定目录下的目录