Poj2749 Building Roads
来源:互联网 发布:简约博客源码 编辑:程序博客网 时间:2024/06/03 19:23
有N个点,每个点向S1或S2连边。有一些恩怨情仇限制某些对点不能同时连向同一点,而某些对点必须同时连向同一点。每个点到S1和S2都有距离,我们要求可行方案中最大的两点间通过所连的S1(S2)到达彼此的距离最小是多少。
除了恩怨情仇外的限制再加上二分出的距离的限制来做2-SAT判定就好了。
#include<cmath>#include<stack>#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>using namespace std;struct edge { int x,y,next; edge(){} edge(int _x,int _y,int _nt):x(_x),y(_y),next(_nt){}} e[ 1000005 ];int head[2000],tot = 0;inline void addedge(int x,int y) { e[++tot] = edge(x,y,head[x]); head[x] = tot;}bool ins[2000];int inc[2000],dfn[2000],low[2000],SCC,T;stack<int>sta;void tarjan(int x){ dfn[x] = low[x] = ++T; sta.push(x); ins[x] = 1; for (int i = head[x]; i; i = e[i].next) { int y = e[i].y; if( ! dfn[y] ) { tarjan(y); low[x] = min(low[x], low[y]); }else if( ins[y] && dfn[y] < low[x]) low[x] = dfn[y]; } if( low[x] == dfn[x] ){ SCC++; while(1) { int y = sta.top(); sta.pop(); ins[y] = 0; inc[y] = SCC; if (x == y ) break; } }}struct point { int x,y; point(){} point(int _x,int _y):x(_x),y(_y){}} a[2005],s[3];int dis(point a,point b) { return abs(a.x-b.x) + abs(a.y-b.y);}int N,A,B;int e1[2005][2],e2[2005][2];int d1[2005],d2[2005],d12;bool judge(int d) { memset(head,0,sizeof head); tot = 0; for (int i = 1; i <= A; i++) { addedge(e1[i][0], e1[i][1]+N); addedge(e1[i][0]+N, e1[i][1]); addedge(e1[i][1], e1[i][0]+N); addedge(e1[i][1]+N, e1[i][0]); } for (int i = 1; i <= B; i++) { addedge(e2[i][0], e2[i][1]); addedge(e2[i][0]+N, e2[i][1]+N); addedge(e2[i][1], e2[i][0]); addedge(e2[i][1]+N, e2[i][0]+N); } for (int i = 1; i <= N; i++) for (int j = i+1; j <= N; j++) { if ( d1[i] + d1[j] > d ) { addedge(i,j+N); addedge(j,i+N); } if ( d2[i] + d2[j] > d ) { addedge(i+N,j); addedge(j+N,i); } if ( d1[i] + d12 + d2[j] > d ) { addedge(i,j); addedge(j+N,i+N); } if ( d2[i] + d12 + d1[j] > d ) { addedge(i+N,j+N); addedge(j,i); } } SCC = 0; T = 0; memset(ins,0,sizeof ins); memset(dfn,0,sizeof dfn); for (int i = 1; i <= N<<1; i++) if( ! dfn[i] ) tarjan(i); for (int i = 1; i <= N; i++) if( inc[i] == inc[i+N] ) return 0; return 1;}int main() { scanf("%d%d%d",&N,&A,&B); scanf("%d%d%d%d",&s[1].x,&s[1].y,&s[2].x,&s[2].y); int L = 0x3f3f3f3f,R = -1 ,mid,ans; d12 = dis(s[1],s[2]); for (int i = 1; i <= N; i++) { scanf("%d%d",&a[i].x,&a[i].y); d1[i] = dis(a[i], s[1]); d2[i] = dis(a[i], s[2]); L = min(L,min(d1[i],d2[i])); R = max(R,max(d1[i],d2[i])); } L <<= 1, (R<<=1)+= d12, ans = 0x3f3f3f3f; for (int i = 1; i <= A; i++) scanf("%d%d",&e1[i][0],&e1[i][1]); for (int i = 1; i <= B; i++) scanf("%d%d",&e2[i][0],&e2[i][1]); while( L <= R) { int mid = (L + R) >> 1; if( judge(mid) ) ans = mid,R=mid-1; else L = mid + 1; } if( ans == 0x3f3f3f3f ) ans = -1; printf("%d\n",ans);}
0 0
- Poj2749 Building Roads
- poj2749 Building roads
- poj2749 Building roads
- POJ2749 Building roads
- POJ2749——Building roads
- poj2749 Building roads 2-sat
- POJ2749 Building roads【2-SAT】
- poj2749:Building roads(2-SAT)
- 2-SAT——6.0(poj2749 Building roads)
- 【二分+2-SAT验证】POJ2749[Building roads]题解
- Building Roads
- POJ 3625 Building Roads
- POJ3625 Building Roads
- Building Roads(3625)
- poj 3625 Building Roads
- POJ 2749 Building Roads
- poj 2749 Building roads
- Pku 2749 Building roads
- 最小生成树_Prim
- Android5.1中surface和CpuConsumer下生产者和消费者间的处理框架简述
- 定位 -- 百度地图SDK
- 鸟哥Java学习之集合框架--常用对象API
- 第15章:source files and programs
- Poj2749 Building Roads
- valid-sudoku判断是否是有效数独
- Maven生命周期和插件
- android中图片的三级缓存cache策略(内存/文件/网络)
- 深度学习系列文章之二上:win7+Ubantu双系统装机步骤(硬盘安装)
- node.js 和 express 框架学习笔记(1)
- POJ 2485-Highways(最小生成树裸题-prim/kruskal)
- Android Activity runonUiThread
- 强悍的 ubuntu —— 查看软件版本及安装位置