zoukankan      html  css  js  c++  java
  • [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;
    }
    
    
  • 相关阅读:
    day01--计算机硬件基础笔记
    22 Jun 18 Django,ORM
    21 Jun 18 Django,ORM
    20 Jun 18 复习, mysql
    20 Jun 18 Django,ORM
    19 Jun 18 复习, 正则表达式
    19 Jun 18 Django
    15 Jun 18 复习, shutil模块
    15 Jun 18 Django
    14 Jun 18 复习, form表单
  • 原文地址:https://www.cnblogs.com/mrha/p/7856125.html
Copyright © 2011-2022 走看看