POJ 2749 Building roads【二分+2-sat】
2012-10-01 14:49
387 查看
题意: 已知有 n 个农场,知道了每个农场的坐标,有两个中转站 s1,s2, 每个农场和其中一个中转站相连,
有 A 对hate关系 a,b 表示 a 和 b 农场不能和同一个中转站相连,
有 B 对Fs 关系 a,b 表示 a 和 b 农场必须和同一个中转站相连,
求一种连接方案,在满足条件 A,B的条件下,图中任意两个农场的最大距离最小。
分析: i 表示第 i 个农场和中转站 s1 相连,i + n 表示第 i 个农场和中转站 s2 相连,
建图:
在 A 条件中,对于每对关系 i , j 连边
i -> j + n
i + n -> j
j ->i + n
j + n ->i
表示 i 和 j 不能和同一个中转站相连
在 B 条件中,对于没对关系的建边方式和上面类似,
对每一次枚举的 距离 di,
枚举任意两个农场 i , j
如果 距离 i->s1->j 大于 di , 连边
i -> j+n , j -> i+n 表示 i , j 农场不能同时和 s1 相连
如果 距离 i->s2->j 大于 di , 连边
i + n -> j , j + n -> i 表示 i , j 农场不能同时和 s2 相连
如果 距离 i->s1->s2->j 大于 di ,连边
i -> j , j + n -> i + n 表示 如果 i 农场和 s1 相连,则 j 农场必须和 s1 相连,如果 j 农场和 s2 相连,则 i 必须和s2 相连
如果 距离 i->s2->s1->j 大于 di ,连边
j -> i , i + n -> j + n 表示 如果 j 农场和 s1 相连,则 i 农场必须和 s1 相连,如果 i 农场和 s2 相连,则 j 必须和s2 相连
对于每次枚举的距离 di 判断是否有冲突情况即可。
有 A 对hate关系 a,b 表示 a 和 b 农场不能和同一个中转站相连,
有 B 对Fs 关系 a,b 表示 a 和 b 农场必须和同一个中转站相连,
求一种连接方案,在满足条件 A,B的条件下,图中任意两个农场的最大距离最小。
分析: i 表示第 i 个农场和中转站 s1 相连,i + n 表示第 i 个农场和中转站 s2 相连,
建图:
在 A 条件中,对于每对关系 i , j 连边
i -> j + n
i + n -> j
j ->i + n
j + n ->i
表示 i 和 j 不能和同一个中转站相连
在 B 条件中,对于没对关系的建边方式和上面类似,
对每一次枚举的 距离 di,
枚举任意两个农场 i , j
如果 距离 i->s1->j 大于 di , 连边
i -> j+n , j -> i+n 表示 i , j 农场不能同时和 s1 相连
如果 距离 i->s2->j 大于 di , 连边
i + n -> j , j + n -> i 表示 i , j 农场不能同时和 s2 相连
如果 距离 i->s1->s2->j 大于 di ,连边
i -> j , j + n -> i + n 表示 如果 i 农场和 s1 相连,则 j 农场必须和 s1 相连,如果 j 农场和 s2 相连,则 i 必须和s2 相连
如果 距离 i->s2->s1->j 大于 di ,连边
j -> i , i + n -> j + n 表示 如果 j 农场和 s1 相连,则 i 农场必须和 s1 相连,如果 i 农场和 s2 相连,则 j 必须和s2 相连
对于每次枚举的距离 di 判断是否有冲突情况即可。
#include<stdio.h> #include<string.h> #define clr(x)memset(x,0,sizeof(x)) #define min(a,b)(a)<(b)?(a):(b) #define max(a,b)(a)>(b)?(a):(b) #define maxn 1005 #define maxm 1000000 struct node { int to,next; }e[maxm]; int tot; int head[maxn]; void add(int s,int t) { e[tot].to=t; e[tot].next=head[s]; head[s]=tot++; } int ti,sn,top,n; int dfn[maxn]; int low[maxn]; int ins[maxn]; int sta[maxn]; int col[maxn]; void tarjan(int u) { dfn[u]=low[u]=++ti; ins[u]=1; sta[++top]=u; int i,k; for(i=head[u];i;i=e[i].next) { k=e[i].to; if(dfn[k]==0) { tarjan(k); low[u]=min(low[u],low[k]); } else if(ins[k]) low[u]=min(low[u],dfn[k]); } if(dfn[u]==low[u]) { sn++; do { k=sta[top--]; ins[k]=0; col[k]=sn; }while(k!=u); } } struct point { int x,y; }p[maxn],s1,s2; int ab(int x) { return x>0?x:-x; } int dis(point a,point b) { return ab(a.x-b.x)+ab(a.y-b.y); } struct Fs { int a,b; }hate[1005],fs[1005]; int A,B; int g[505][505]; bool ok(int di) { tot=1; clr(head); int i,j; for(i=1;i<=A;i++) { add(hate[i].a,hate[i].b+n); add(hate[i].a+n,hate[i].b); add(hate[i].b,hate[i].a+n); add(hate[i].b+n,hate[i].a); } for(i=1;i<=B;i++) { add(fs[i].a,fs[i].b); add(fs[i].a+n,fs[i].b+n); add(fs[i].b,fs[i].a); add(fs[i].b+n,fs[i].a+n); } for(i=1;i<=n;i++) for(j=i+1;j<=n;j++) { if(g[0][i]+g[0][j]>di) add(i,j+n),add(j,i+n); if(g[i][0]+g[j][0]>di) add(i+n,j),add(j+n,i); if(g[0][i]+g[0][0]+g[j][0]>di) add(i,j),add(j+n,i+n); if(g[0][j]+g[0][0]+g[i][0]>di) add(j,i),add(i+n,j+n); } sn=top=ti=0; clr(dfn); for(i=1;i<=2*n;i++) if(!dfn[i]) tarjan(i); for(i=1;i<=n;i++) if(col[i]==col[i+n]) return 0; return 1; } int main() { int i,j,k; while(scanf("%d%d%d",&n,&A,&B)!=EOF) { 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); int l=0,r=5000000,mid,res; for(i=1;i<=n;i++) for(j=i+1;j<=n;j++) g[i][j]=g[j][i]=dis(p[i],p[j]); for(i=1;i<=n;i++) { g[0][i]=dis(s1,p[i]); g[i][0]=dis(p[i],s2); } g[0][0]=dis(s1,s2); for(i=1;i<=A;i++) scanf("%d%d",&hate[i].a,&hate[i].b); for(i=1;i<=B;i++) scanf("%d%d",&fs[i].a,&fs[i].b); res=-1; while(l<=r) { mid=(l+r)>>1; if(ok(mid)) { res=mid; r=mid-1; } else l=mid+1; } printf("%d\n",res); } return 0; }
相关文章推荐
- POJ 2749|Building roads|2-SAT|二分答案
- Poj 2749 & Hdu 1815 Building roads (2-SAT + 二分 建图)
- poj 2749 Building roads 【2-sat + 二分】【建图较复杂】【好题】
- Poj 2749 Building roads【二分+2-Sat----------Tarjan强连通】
- |poj 2749|2-SAT|二分|Building roads
- POJ 2749 && HDU 1815 Building roads(2-SAT+二分)
- poj 2749 & hdu 1815 Building roads(2-SAT + 二分,好题)
- poj 2749 Building roads(2-sat+二分)
- POJ 2749 - Building roads(2-SAT+二分)
- POJ 2749 || HDU 1815 Building roads 2-sat
- POJ 2749 二分+2-sat判定
- POJ 2749--Building roads(2-SAT)
- POJ 2749 Building roads 2-sat+二分答案
- POJ 2749 Building roads (2-SAT)
- poj 2749 Building roads(2-sat)
- POJ 2749 Building roads (2-sat)
- POJ 2749 Building roads(2-SAT)
- POJ-2749-Building roads(2-sat)
- poj 2749 Building roads #二分+2-sat
- poj 2749 Building roads 2-sat