生活随笔
收集整理的這篇文章主要介紹了
[poj] 2749 building roads
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
原題
2-SAT+二分答案!
最小的最大值,這肯定是二分答案。而我們要2-SATcheck是否在該情況下有可行解。
對于目前的答案limit,首先把愛和恨連邊,然后我們n^2枚舉每兩個點通過判斷距離來實現連邊,然后跑2-SAT判斷是否有可行解
O(n^2logn)
想起來和聽起來都很難寫,事實上還好吧…
#include<cstdio>
#include<algorithm>
#include<stack>
#include<cstring>
#define inf 97797977
#define N 510
using namespace std;
int n,m,A,B,lovex[2*N],lovey[2*N],hatex[2*N],hatey[2*N],dis1[N],dis2[N],dis,sx1,sx2,sy1,sy2,x[N],y[N],head[2*N];
int bel[2*N],cnt=1,l,r=inf,dfn[2*N],low[2*N],t,mid,sum;
stack <int> stk;
bool instk[2*N];
struct hhh
{int to,next;
}edge[10*N*N];int read()
{int ans=0,fu=1;char j=getchar();for (;(j<'0' || j>'9') && j!='-';j=getchar()) ;if (j=='-') j=getchar(),fu=-1;for (;j>='0' && j<='9';j=getchar()) ans*=10,ans+=j-'0';return ans*fu;
}void add(int u,int v)
{edge[cnt].to=v;edge[cnt].next=head[u];head[u]=cnt++;
}bool build()
{for (int i=1;i<=B;i++){add(lovex[i],lovey[i]);add(lovey[i],lovex[i]);add(lovex[i]+n,lovey[i]+n);add(lovey[i]+n,lovex[i]+n);}for (int i=1;i<=A;i++){add(hatex[i],hatey[i]+n);add(hatex[i]+n,hatey[i]);add(hatey[i]+n,hatex[i]);add(hatey[i],hatex[i]+n);}for (int i=1;i<=n;i++)for (int j=i+1;j<=n;j++){int t=0;if (dis1[i]+dis+dis2[j]>mid){add(i,j);add(j+n,i+n);t++;}if (dis2[i]+dis+dis1[j]>mid){add(i+n,j+n);add(j,i);t++;}if (dis1[i]+dis1[j]>mid){add(i,j+n);add(j,i+n);t++;}if (dis2[i]+dis2[j]>mid){add(i+n,j);add(j+n,i);t++;}if (t==4) return 0;}return 1;
}void Tarjan(int u)
{dfn[u]=low[u]=++t;stk.push(u);instk[u]=1;for (int i=head[u],v;i;i=edge[i].next){v=edge[i].to;if (!dfn[v]){Tarjan(v);low[u]=min(low[u],low[v]);}else if (instk[v]) low[u]=min(low[u],dfn[v]);}if (low[u]==dfn[u]){sum++;int t;do{t=stk.top();bel[t]=sum;stk.pop();instk[t]=0;}while(t!=u);}
}bool check()
{for (int i=1;i<=n;i++)if (bel[i]==bel[i+n]) return 0;return 1;
}int get1(int i)
{return abs(sx1-x[i])+abs(sy1-y[i]);
}int get2(int i)
{return abs(sx2-x[i])+abs(sy2-y[i]);
}int main()
{n=read();A=read();B=read();sx1=read();sy1=read();sx2=read();sy2=read();dis=abs(sx1-sx2)+abs(sy1-sy2);for (int i=1;i<=n;i++){x[i]=read();y[i]=read();}for (int i=1;i<=A;i++){hatex[i]=read();hatey[i]=read();}for (int i=1;i<=B;i++){lovex[i]=read();lovey[i]=read();}for (int i=1;i<=n;i++){dis1[i]=get1(i);dis2[i]=get2(i);}while (l<r){mid=(l+r)>>1;cnt=1;memset(dfn,0,sizeof(dfn));memset(bel,0,sizeof(bel));memset(head,0,sizeof(head));if (build()){t=1;sum=1;for (int i=1;i<=2*n;i++)if (!dfn[i]) Tarjan(i);if (check()) r=mid;else l=mid+1;}else l=mid+1;}printf("%d",l>=inf?-1:l);return 0;
}
轉載于:https://www.cnblogs.com/mrha/p/7856125.html
總結
以上是生活随笔為你收集整理的[poj] 2749 building roads的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。