hdu 3622 (2-SAT+二分)

来源:互联网 发布:mac os 英文字体 编辑:程序博客网 时间:2024/04/29 22:04

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









#include<cstdio>#include<cstring>#include<cmath>#include<stack>#define N 500const 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;}