poj 2749 Building roads
2013-10-13 21:46
246 查看
把每个牧场分别和两个中转站其中一个连接。使曼哈顿距离最大值最小。
要把每个牧场拆成两个点,一个表示连到第一中转站,一个表示连到第二个中转站。
记录牧场之间的曼哈顿距离,然后二分,对于当前距离,如果满足连一条边,如果两个牧场不友好,他们不相同牧场连一条边,如果两个牧场友好,则把连到同一个牧场的点连一条边。
要把每个牧场拆成两个点,一个表示连到第一中转站,一个表示连到第二个中转站。
记录牧场之间的曼哈顿距离,然后二分,对于当前距离,如果满足连一条边,如果两个牧场不友好,他们不相同牧场连一条边,如果两个牧场友好,则把连到同一个牧场的点连一条边。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; const int maxn=1004005; const int maxm=2005; int dis[maxm],gra[maxm][maxm]; int hate[maxm],frid[maxm]; int hax[maxm],hay[maxm],frx[maxm],fry[maxm]; int head[maxm],next[maxn],to[maxn]; int dfn[maxm],low[maxm],vis[maxm],stk[maxm],scc[maxm]; int tot,top,cnt,id,s1s2,fr,ht; void addEdage(int u,int v) { next[tot]=head[u],to[tot]=v,head[u]=tot++; } void init() { memset(head,-1,sizeof(head)); memset(dfn,0,sizeof(dfn)); memset(vis,0,sizeof(vis)); tot=top=cnt=id=0; } void tarjan(int v) { dfn[v]=low[v]=++cnt; vis[v]=1; stk[++top]=v; for(int i=head[v];i!=-1;i=next[i]) { int u=to[i]; if(!dfn[u]) { tarjan(u); low[v]=min(low[v],low[u]); } else if(vis[u]) { low[v]=min(low[v],dfn[u]); } } if(low[v]==dfn[v]) { id++; while(true) { int u(stk[top--]); vis[u]=0; scc[u]=id; if(u==v) break; } } } bool judge(int mid,int n) { init(); for(int i=0;i<fr;i++) { addEdage(2*(frx[i]-1)+1,2*(fry[i]-1)+1); addEdage(2*(frx[i]-1),2*(fry[i]-1)); addEdage(2*(fry[i]-1)+1,2*(frx[i]-1)+1); addEdage(2*(fry[i]-1),2*(frx[i]-1)); } for(int i=0;i<ht;i++) { addEdage(2*(hax[i]-1)+1,2*(hay[i]-1)); addEdage(2*(hax[i]-1),2*(hay[i]-1)+1); addEdage(2*(hay[i]-1)+1,2*(hax[i]-1)); addEdage(2*(hay[i]-1),2*(hax[i]-1)+1); } for(int i=0;i<2*n;i++) { for(int j=0;j<2*n;j++) { if(gra[i][j]>mid) addEdage(i,j^1); } } for(int i=0;i<2*n;i++) if(!dfn[i])tarjan(i); for(int i=0;i<2*n;i+=2) if(scc[i]==scc[i+1]) return 0; return 1; } void solve(int n,int l,int r) { r++; int mid,tmp=r; while(l<r) { mid=(l+r)>>1; if(judge(mid,n)) r=mid; else l=mid+1; } if(r!=tmp) printf("%d\n",r); else printf("-1\n"); } int main() { //freopen("in.txt","r",stdin); int n,sx1,sy1,sx2,sy2; int l=1<<30,r=0; scanf("%d%d%d",&n,&ht,&fr); scanf("%d%d%d%d",&sx1,&sy1,&sx2,&sy2); s1s2=abs(sx1-sx2)+abs(sy1-sy2); for(int i=0,x,y;i<n;i++) { scanf("%d%d",&x,&y); dis[i*2]=abs(x-sx1)+abs(y-sy1); dis[2*i+1]=abs(x-sx2)+abs(y-sy2); } memset(gra,0,sizeof(gra)); for(int i=0;i<2*n;i++) { for(int j=i+1;j<2*n;j++) { if(i/2!=j/2) { if(i%2!=j%2) gra[i][j]=gra[j][i]=dis[i]+dis[j]+s1s2; else gra[i][j]=gra[j][i]=dis[i]+dis[j]; l=min(l,gra[i][j]); r=max(r,gra[i][j]); } } } for(int i=0;i<ht;i++) scanf("%d%d",&hax[i],&hay[i]); for(int i=0;i<fr;i++) scanf("%d%d",&frx[i],&fry[i]); solve(n,l,r); return 0; }
相关文章推荐
- POJ-2749-Building roads
- poj 2749 Building roads
- Poj 2749 & Hdu 1815 Building roads (2-SAT + 二分 建图)
- POJ_2749 Building roads 2-Sat
- POJ 2749--Building roads(2-SAT)
- poj 2749 Building roads
- POJ 2749 Building roads 已翻译
- poj 2749 Building roads(2-sat+二分)
- poj 2749 Building roads 【2-sat + 二分】【建图较复杂】【好题】
- poj 2749 Building roads
- HDU 1815, POJ 2749 Building roads(2-sat)
- poj 2749 Building roads 2-SAT
- POJ 2749 - Building roads(2-SAT+二分)
- POJ 2749 Building roads【二分+2-sat】
- HDU 1815, POJ 2749 Building roads(2-sat)
- poj2749 Building roads
- poj 2749 Building roads 2-sat
- poj 2749 building roads
- POJ 2749 Building roads(2-ST)
- POJ2749——Building roads