首页 > 代码库 > ZOJ 3717
ZOJ 3717
这题是二分+2SAT.
总结一下SAT题的特征。首先,可能会存在二选一的情况,然后会给出一些矛盾。据这些矛盾加边,再用SAT判定。
这一道题好像不能直接用printf("%0.3lf"),因为这个是四舍五入的,这道题好像不能四舍五入,只好选减去0.0005再按这个格式输出了。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <cmath> 6 #include <stdlib.h> 7 #define oo 1000000007 8 #define eps 1e-4 9 using namespace std; 10 const int MAXN=420; 11 const int MAXM=320000; 12 struct b{ 13 int x,y,z; 14 }ball[MAXN]; 15 double dis[MAXN][MAXN]; 16 int head[MAXN],dfn[MAXN],low[MAXN],tot,stop,indx,belong[MAXN],pat; 17 int st[MAXN]; 18 bool stack[MAXN]; 19 int n; 20 struct e{ 21 int u,v; 22 int next; 23 }edge[MAXM]; 24 25 void addedge(int u,int v){ 26 edge[tot].u=u; 27 edge[tot].v=v; 28 edge[tot].next=head[u]; 29 head[u]=tot++; 30 } 31 32 void tarjan(int u){ 33 int v; 34 dfn[u]=low[u]=++indx; 35 st[stop++]=u; 36 stack[u]=true; 37 for (int e=head[u];e!=-1;e=edge[e].next){ 38 v=edge[e].v; 39 if (dfn[v]==0) { 40 tarjan(v) ; 41 low[u] = min(low[u], low[v]) ; 42 } 43 else if (stack[v]) { 44 low[u] = min(low[u], dfn[v]) ; 45 } 46 } 47 if (dfn[u] == low[u]) { 48 pat++; 49 do{ 50 v = st[--stop]; 51 belong[v]=pat; 52 stack[v]=false; 53 }while(u!= v); 54 } 55 } 56 57 bool slove(double leng){ 58 int a,b; tot=0; indx=0; stop=0; pat=-1; 59 memset(head,-1,sizeof(head)); 60 for(int i=0;i<n;i++){ 61 a=i; 62 for(int j=i+1;j<n;j++){ 63 b=j; 64 if(leng*2>dis[a*2][b*2]){ 65 addedge(2*a+1,b*2); 66 addedge(b*2+1,a*2); 67 } 68 if(leng*2>dis[a*2][b*2+1]){ 69 addedge(a*2+1,b*2+1); 70 addedge(b*2,a*2); 71 } 72 if(leng*2>dis[a*2+1][b*2]){ 73 addedge(a*2,b*2); 74 addedge(b*2+1,a*2+1); 75 } 76 if(leng*2>dis[a*2+1][b*2+1]){ 77 addedge(a*2,b*2+1); 78 addedge(b*2,a*2+1); 79 } 80 } 81 } 82 memset(dfn,0,sizeof(dfn)); 83 memset(low,0,sizeof(low)); 84 memset(stack,false,sizeof(stack)); 85 memset(belong,-1,sizeof(belong)); 86 for(int i=0;i<2*n;i++){ 87 if(dfn[i]==0){ 88 tarjan(i); 89 } 90 } 91 bool flag=true; 92 for(int i=0;i<n;i++){ 93 if(belong[i*2]==belong[i*2+1]){ 94 flag=false; 95 break; 96 } 97 } 98 return flag; 99 }100 101 int main(){102 double xi,yi,zi;103 while(scanf("%d",&n)!=EOF){104 for(int i=0;i<2*n;i++){105 scanf("%d%d%d",&ball[i].x,&ball[i].y,&ball[i].z);106 i++;107 scanf("%d%d%d",&ball[i].x,&ball[i].y,&ball[i].z);108 }109 double high=oo,lown=0; double tmp;110 for(int i=0;i<2*n;i++){111 for(int j=i;j<2*n;j++){112 xi=ball[i].x-ball[j].x;113 yi=ball[i].y-ball[j].y;114 zi=ball[i].z-ball[j].z;115 tmp=sqrt(xi*xi+yi*yi+zi*zi);116 dis[i][j]=dis[j][i]=tmp;117 }118 }119 double ans;120 while(lown<high-eps){121 double mid=(high+lown)/2;122 if(slove(mid)){123 ans=mid;124 lown=mid;125 }126 else high=mid;127 }128 printf("%0.3lf\n",ans-0.0005);129 }130 return 0;131 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。