poj 2749 2-SAT问题
思路:首先将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问题相关推荐
- 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
POJ_2749 一开始没有想到去二分距离,看了别人的报告之后恍然大悟. 这是一个2-SAT的问题,首先我们要去找到核心变量,可以看出每个牛的有着要么和S1相连,要么和S2相连的逻辑关系,因此可以把奶 ...
- [poj] 2749 building roads
原题 2-SAT+二分答案! 最小的最大值,这肯定是二分答案.而我们要2-SATcheck是否在该情况下有可行解. 对于目前的答案limit,首先把爱和恨连边,然后我们n^2枚举每两个点通过判断距离来 ...
- poj pku图论、网络流入门题总结、汇总
poj pku图论.网络流入门题总结.汇总 分类: acm图论 2010-08-25 18:49 243人阅读 评论(0) 收藏 举报 网络算法networkgraphconstructioninte ...
- POJ 图论分类 + DP(较全 自己又加了点)
DP -----------动态规划 状态压缩DP 2411 (棋盘规模较大)状态压缩DP+DFS+滚动数组 2664 (棋盘规模较小)直接递推即可(DP) 2506 (棋盘规模较小)直接递推即可(D ...
- 《挑战程序设计竞赛(第2版)》习题册攻略
本项目来源于GitHub 链接: 项目GitHub链接 1 前言 项目为<挑战程序设计竞赛(第2版)>习题册攻略,已完结.可配合书籍或笔记,系统学习算法. 题量:约200道,代码注释内含详 ...
- [kuangbin]各种各样的题单
[kuangbin]各种各样的题单 专题1 简单搜索 POJ 1321 POJ 2251 POJ 3278 POJ 3279 POJ 1426 POJ 3126 POJ 3087 POJ 3414 F ...
- (转)2-sat 专题
[2-sat]专题- 2-sat是一个逻辑性很强的算法,但是其套路比较固定,所以不是很热,题目很少,但也不乏AC后让人大呼爽快的好题,下面放出两篇极品论文还有几道题目的题解以供交流-- 2-sat学习 ...
最新文章
- 第一次作业:阅读优秀博文谈感想
- linux 下mongo 基础配置
- build muduo网络库undefined reference to问题
- usb host控制devie进入suspend模式
- [渝粤教育] 西南科技大学 数控机床与编程 在线考试复习资料
- 本地仓库settings.xml中使用阿里的仓库
- LeetCode:每日一题(2020.4.14)
- Python中List,tuple,Dictionary之间的区别
- 局域网邮件服务器搭建地址薄更新,搭建局域网邮件服务器
- 接口交互时的URL带有日期格式的参数,注意拼装地址中的特殊符号(如空格等)
- Oracle 获取当前日期及日期格式
- linux创建2g文件,嵌入式 创建一个2G的空文件(Linux命令dd)
- cocos2d-x 2.2 CocoStudio动画和界面编辑器按钮控制以及场景编辑器使用
- 多目标狼群优化算法(MGWO)
- 树莓派的蓝牙通讯(bluez、gattlib)
- 高电平复位还是低电平复位?
- downwell什么意思_downwelling_downwelling是什么意思翻译
- java日志:一、JUL使用
- Java 微信二维码支付
- 自动定时发送邮件的方法 —— 定时执行专家V6.8