hdu 3622 (2-SAT+二分)

每对点选一个,2-SAT问题,不知怎么处理半径的问题,看到网上说二分,想了想,用二分找出每个半径的可能性,一直找到最大的,用链表写了,结果Memory Limit Exceeded,









#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#define N 500
const double eps=1e-10;
using namespace std;
int n,low[N],dfs[N],ins[N],idx,ans,belong[N],num,first[N];
double map[N][N];
struct eage
{
    int ed,next;   
}E[N*N];
struct node
{
    int x,y;
}NM[N];
void addeage(int x,int y)
{
    E[num].ed=y;
	E[num].next=first[x];
	first[x]=num++;
}
double dis(node a,node b)
{
    return sqrt(1.0*((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)));
}
void inst()
{
    memset(dfs,-1,sizeof(dfs));
    memset(low,0,sizeof(low));
    memset(first,-1,sizeof(first));
    memset(belong,0,sizeof(belong));
    ans=idx=1;num=0;
}
stack<int>Q;
void Tarjan(int x)
{
    int v;
    dfs[x]=low[x]=idx++;
    Q.push(x);
    ins[x]=1;
    for(int p=first[x];p!=-1;p=E[p].next)
    {
        v=E[p].ed;
        if(dfs[v]==-1)
        {
            Tarjan(v);
            low[x]=low[x]>low[v]?low[v]:low[x];
        }
        else if(ins[v]==1)
        {
            low[x]=low[x]>dfs[v]?dfs[v]:low[x];
        }
    }
    if(low[x]==dfs[x])
    {
        while(1)
        {
            v=Q.top();
            Q.pop();
            ins[v]=0;
            belong[v]=ans;
            if(v==x)break;
        }
        ans++;
    }
}

int judge(double d)
{
    int i,j;
    inst();
    for(i=0;i<n;i++)
        for(j=i+1;j<n;j++)
        {
            if(map[i][j]<d){addeage(i,j+n);addeage(j,i+n);}
            if(map[i][j+n]<d){addeage(i,j);addeage(j+n,i+n);}
            if(map[i+n][j]<d){addeage(i+n,j+n);addeage(j,i);}
            if(map[i+n][j+n]<d){addeage(i+n,j);addeage(j+n,i);}
        }
        for(i=0;i<2*n;i++)
        {
            if(dfs[i]==-1)
                Tarjan(i);
        }
        for(i=0;i<n;i++)
        {
            if(belong[i]==belong[i+n])
                return 0;
        }
        return 1;

}
int main()
{
    int i,j;
    double min,max,mmax,mid;
    while(scanf("%d",&n)!=-1)
    {
        for(i=0;i<n;i++)
            scanf("%d%d%d%d",&NM[i].x,&NM[i].y,&NM[i+n].x,&NM[i+n].y);
        min=9999999;
        max=-1;
        for(i=0;i<2*n;i++)
            for(j=i+1;j<n*2;j++)
            {
                double d=dis(NM[i],NM[j]);
                if(min>d)min=d;
                if(max<d)max=d;
                map[i][j]=map[j][i]=d;
            }
            mmax=min;
            while(fabs(max-min)>=eps)
            {
                mid=(max+min)/2;
                if(judge(mid))
                {
                    if(mmax<mid)mmax=mid;
                    min=mid;
                }
                else max=mid;
            }
            printf("%.2f\n",mmax/2);
    }
    return 0;
}


你可能感兴趣的:(编程,算法,百度,Google,ACM)