Poj2749 Building Roads
2016-06-01 21:24
435 查看
有N个点,每个点向S1或S2连边。有一些恩怨情仇限制某些对点不能同时连向同一点,而某些对点必须同时连向同一点。每个点到S1和S2都有距离,我们要求可行方案中最大的两点间通过所连的S1(S2)到达彼此的距离最小是多少。
除了恩怨情仇外的限制再加上二分出的距离的限制来做2-SAT判定就好了。
除了恩怨情仇外的限制再加上二分出的距离的限制来做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); }
相关文章推荐
- UI进阶 FMDB
- 实在没想到系列——HashMap实现底层细节之keySet,values,entrySet的一个底层实现细节
- iOS——UICollectionView
- <GPS> Learning Neural Network Policies with Guided Policy Search under Unknown Dynamics
- UI(base)--android
- 更新UI 2种方法
- LeetCode-347.Top K Frequent Elements
- getParamValues()
- 普通类中获取request,session
- IOS--如何在UILabel上显示图片
- Duilib 第一课 2016年6月一日
- (Caffe)基本类DataReader、QueuePair、Body(四)
- poj1458 Common Subsequence (dp,最长公共子序列)
- UIDynamic物理仿真 属性方法解释(一篇就OK)
- Fragment的简要介绍
- 改变input的value值,同时在HTML中将value进行改变
- Request的getParameter和getAttribute方法的区别
- Request获取url各种信息的方法
- LeetCode128—Longest Consecutive Sequence
- 1085. Perfect Sequence (25) PAT