2-SAT——6.0(poj2749 Building roads)
来源:互联网 发布:网络好听的歌曲排行榜 编辑:程序博客网 时间:2024/06/06 20:58
poj2749 Building roads
题意是说有 N 个牛栏,现在通过一条通道(s1,s2)把他们连起来,他们之间有一些约束关系,一些牛栏不能连在同一个点,一些牛栏必须连在同一个点,现在问有没有可能把他们都连好,而且满足所有的约束关系,如果可以,输出两个牛栏之间距离最大值的最小情况。
比如牛栏 A 连在 s1 点,牛栏 B 连在 s2 点,那么AB之间的距离为(As1 + s1s2 + s2B);也可以两个牛栏连在同一个点上,比如 A 连在 s1 ,B 也连在 s1 ,那么AB的距离是(As1 + Bs1)。
A 表示连在s1,A‘ 表示连在 s2 ,按照给出的约束关系建边,然后在区间内2分枚举所有可能的解 ans,如果当前解满足条件,那么就意味着 ans 还可以更小,如果不满足,说明当前的 ans 值过大。
#include<iostream>#include<cstdio>#include<cstring>#include<stack>#include<cmath>#include<climits>#define find_min(a,b) (a<b?a:b)#define find_max(a,b) (a>b?a:b)using namespace std;const int N = 2010;struct point{int x,y;};point p[N];struct Edge{int s,e,next;}edge[5*N];int n,e_num,vis_num,cnt,head[N],instack[N],low[N],tim[N],belong[N];void AddEdge(int a,int b){edge[e_num].s=a; edge[e_num].e=b; edge[e_num].next=head[a]; head[a]=e_num++;}int dis_m(point a,point b){return abs(a.x-b.x)+abs(a.y-b.y);}stack <int>st;void tarjan(int x){ int i; tim[x]=low[x]=++vis_num; instack[x]=1; st.push(x); for(i=head[x];i!=-1;i=edge[i].next){ int u=edge[i].e; if(tim[u]==-1){ tarjan(u); if(low[x]>low[u])low[x]=low[u]; } else if(instack[u] && low[x]>tim[u])low[x]=tim[u]; } if(low[x]==tim[x]){ cnt++; do{ i=st.top(); st.pop(); instack[i]=0; belong[i]=cnt; }while(i!=x); }}void init(){vis_num=cnt=0; memset(instack,0,sizeof(instack)); memset(belong,-1,sizeof(belong)); memset(tim,-1,sizeof(tim)); memset(low,0,sizeof(low));}int main(){int A,B;int i,j,left,right,mid,ans;int hate[N][2],like[N][2];point s1,s2;while(~scanf("%d%d%d",&n,&A,&B)){scanf("%d%d%d%d",&s1.x,&s1.y,&s2.x,&s2.y);int len=dis_m(s1,s2);int min=INT_MAX;int max=INT_MIN;for(i=0;i<n;i++){scanf("%d%d",&p[i].x,&p[i].y);min=find_min(min, find_min(dis_m(p[i],s1),dis_m(p[i],s2)) );max=find_max(max, find_max(dis_m(p[i],s1),dis_m(p[i],s2)) );}for(i=0;i<A;i++){scanf("%d%d",&hate[i][0],&hate[i][1]);hate[i][0]--; hate[i][1]--;}for(i=0;i<B;i++){scanf("%d%d",&like[i][0],&like[i][1]);like[i][0]--; like[i][1]--;}left=2*min; right=2*max+len; ans=INT_MAX;while(left<=right){e_num=0;memset(head,-1,sizeof(head));for(i=0;i<A;i++){AddEdge(2*hate[i][0],2*hate[i][1]+1);AddEdge(2*hate[i][0]+1,2*hate[i][1]);AddEdge(2*hate[i][1],2*hate[i][0]+1);AddEdge(2*hate[i][1]+1,2*hate[i][0]);}for(i=0;i<B;i++){AddEdge(2*like[i][0],2*like[i][1]);AddEdge(2*like[i][0]+1,2*like[i][1]+1);AddEdge(2*like[i][1],2*like[i][0]);AddEdge(2*like[i][1]+1,2*like[i][0]+1);}mid=(left+right)/2;for(i=0;i<n;i++){for(j=i+1;j<n;j++){if(i!=j){if(dis_m(p[i],s1)+dis_m(p[j],s1)>mid){//点 i 到 s1 的距离加上点 j 到 s1 的距离大于所枚举的最大值,所以矛盾AddEdge(2*i,2*j+1);AddEdge(2*j,2*i+1);}if(dis_m(p[i],s2)+dis_m(p[j],s2)>mid){AddEdge(2*i+1,2*j);AddEdge(2*j+1,2*i);}if(dis_m(p[i],s1)+dis_m(p[j],s2)+len>mid){AddEdge(2*i,2*j);AddEdge(2*j+1,2*i+1);}if(dis_m(p[j],s1)+dis_m(p[i],s2)+len>mid){AddEdge(2*j,2*i);AddEdge(2*i+1,2*j+1);}}}}init();for(i=0;i<2*n;i++){if(tim[i]==-1)tarjan(i);}int flag=1;for(i=0;i<n;i++){if(belong[2*i]==belong[2*i+1]){flag=0;break;}}if(flag){ans=find_min(mid,ans); right=mid-1;}else left=mid+1;}printf("%d\n",ans<INT_MAX?ans:-1);}return 0;}
- 2-SAT——6.0(poj2749 Building roads)
- poj2749:Building roads(2-SAT)
- poj2749 Building roads 2-sat
- POJ2749 Building roads【2-SAT】
- POJ2749——Building roads
- 【二分+2-SAT验证】POJ2749[Building roads]题解
- Poj2749 Building Roads
- poj2749 Building roads
- poj2749 Building roads
- POJ2749 Building roads
- POJ 2749 Building roads (2-SAT)
- POJ_2749 Building roads 2-Sat
- HDU1815 Building roads (2-SAT)
- POJ--2749[Building roads] 2-SAT第五题,2—SAT+二分判定
- poj2749 2-SAT判定
- POJ2749-二分,2SAT
- poj2749 2-SAT
- hdu 1815 Building roads(二分+2-sat判定)
- combo 添加listeners,使用 initComponent、constructor 的区别
- 第三部分 MediaPlayer的主要实现分析
- JQuery ajax跨域访问
- mysql 主从复制读写分离实现
- FORM中使用onSubmit="return false"防止表单自动提交,以及submit和button提交表单的区别
- 2-SAT——6.0(poj2749 Building roads)
- JAVA 中常用的几个集合类
- OPhone学习笔记 2
- Android开发之旅:应用程序基础及组件(续)
- 未能正确加载包"visla Studio HTM Editor Package
- js的trim()方法
- GirdView拖动单元格,鼠标释放后更新拖动范围内的单元格
- js中小写字母的编码值大于大写字母的编码值
- iostream和iostream.h的区别 && namespace的用法