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,,sizeof(dfn));
- memset(low,,sizeof(low));
- memset(head,-,sizeof(head));
- memset(id,,sizeof(id));
- memset(vi,,sizeof(vi));
- e=lab=num=top=;
- }
- 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]=;
- for(i=head[u];i!=-;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]=;
- id[i]=num;
- }while(i!=u);
- }
- }
- void build(int mid)
- {
- int i,j;
- init();
- for(i=;i<=n;i++)
- for(j=;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=;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=;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=;i<=n*;i++)
- {
- if(!dfn[i])
- Tarjan(i);
- }
- for(i=;i<=n;i++)
- {
- if(id[i]==id[i+n])
- return ;
- }
- return ;
- }
- int solve()
- {
- int i,j;
- for(i=;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=;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 -;
- int l,r,mid;
- l=;r=;
- while(l+<r)
- {
- mid=(l+r)>>;
- build(mid);
- if(cal())
- r=mid;
- else
- l=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=;i<=n;i++)
- scanf("%d%d",&p[i].x,&p[i].y);
- for(i=;i<=A;i++)
- scanf("%d%d",&hate[i].a,&hate[i].b);
- for(i=;i<=B;i++)
- scanf("%d%d",&Friend[i].a,&Friend[i].b);
- ss=Dis(s1,s2);
- printf("%d\n",solve());
- }
- return ;
- }
poj 2749 2-SAT问题的更多相关文章
- HDU 1815, POJ 2749 Building roads(2-sat)
HDU 1815, POJ 2749 Building roads pid=1815" target="_blank" style="">题目链 ...
- Java实现 POJ 2749 分解因数(计蒜客)
POJ 2749 分解因数(计蒜客) Description 给出一个正整数a,要求分解成若干个正整数的乘积,即a = a1 * a2 * a3 * - * an,并且1 < a1 <= ...
- poj 2749
Building roads Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 6091 Accepted: 2046 De ...
- poj 2749 Building roads (二分+拆点+2-sat)
Building roads Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 6229 Accepted: 2093 De ...
- POJ 2749 2SAT判定+二分
题意:图上n个点,使每个点都与俩个中转点的其中一个相连(二选一,典型2-sat),并使任意两点最大 距离最小(最大最小,2分答案),有些点相互hata,不能选同一个中转点,有些点相互LOVE,必需选相 ...
- poj 1687 Buggy Sat 简单计算几何
暑期集训出的第一道一血 感觉自己萌萌哒…… 这道题本身并没有坑点 仅仅是翻译巨坑…… 解大腿在做B 安学长在做E 我闲着也没事 就一个词一个词翻译F…… 最后感觉…… 题干大多数都看不懂…… 也都没啥 ...
- [poj] 2749 building roads
原题 2-SAT+二分答案! 最小的最大值,这肯定是二分答案.而我们要2-SATcheck是否在该情况下有可行解. 对于目前的答案limit,首先把爱和恨连边,然后我们n^2枚举每两个点通过判断距离来 ...
- POJ 2749 Building roads 2-sat+二分答案
把爱恨和最大距离视为限制条件,可以知道,最大距离和限制条件多少具有单调性 所以可以二分最大距离,加边+check #include<cstdio> #include<algorith ...
- TTTTTTTTTTT POJ 2749 修牛棚 2-Sat + 路径限制 变形
Building roads Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 7019 Accepted: 2387 De ...
随机推荐
- 【C语言】-循环的嵌套
循环的嵌套:当在一个循环语句中嵌入另一个循环时,成为循环的嵌套. 循环嵌套的形式: (1)for语句中嵌入for语句: for ( ) { for ( ) { ... } } (2)for语句嵌入wh ...
- [C语言 - 3] 字符串
字符数组 char * 看做一个特殊的字符数组, 在字符串结束为止添加'\0'结束符 (ASCII码0), 没有\0结尾的是普通的字符数组. 使用双引号定义的字符串自动在尾部加上\0 puts(s)函 ...
- jQuery基础学习5——JavaScript方法获取页面中的元素
给网页中的所有<p>元素添加onclick事件 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN& ...
- c++结束进程的程序
//#include <winbase.h> #include <windows.h> #include <process.h> #include <Tlhe ...
- python的locals()妙用
如果你是个喜欢偷懒的程序员并想让代码看起来更加简明,可以利用 Python 的内建函数 locals() .它返回的字典对所有局部变量的名称与值进行映射.因此,前面的视图可以重写成下面这个样子:def ...
- 通过OAF实现RTF多语言
职责: Oracle XML Publisher 管理员 -->主页 -->模板 -->创建模板 1.定义rtf模板时 在创建模板时,勾选可转换.
- radio select的 option使用
1 radio的使用 <td id="sex">性别: <input type="radio" name=&quo ...
- python中List操作
传送门 官方文件地址 list.append(x): 将x加入列表尾部,等价于a[len(a):] = [x] 例: >>> list1=[1,2,3,4] >>> ...
- CSS 布局总结——变宽度布局
变宽度布局 1-2-1 等比例变宽 总宽度设置 width: 85%; min-width: 650px; (关于IE6的min-width支持,可用) content 设置 width: 66%; ...
- Note of IOS 7 - Views
1. Views presentation: A view (an object whose class is UIView or a subclass of UIView) knows how to ...