首页 > 代码库 > POJ 1556

POJ 1556

枚举每两点的直线,看连线中是否存在线段交点,若存在,即这两点的直线不存在。建图,DIJK就可以了。

  1 #include <iostream>  2 #include <cstdio>  3 #include <cstring>  4 #include <cmath>  5 #include <algorithm>  6 using namespace std;  7   8 const int Max=100;  9 const int M=3000; 10 const int inf=10000; 11 typedef struct pt{ 12     double x,y; 13     int belong; 14 }Point; 15  16 typedef struct pl{ 17     Point start,end; 18 }Pleg; 19 int how_point,how_pleg; 20 Point pot[Max]; 21 Pleg edge[Max]; 22  23 double multi(Point p1, Point p2,Point p0){ 24     return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y); 25 } 26 int head[Max],tot; 27 struct { 28     int u,v; 29     double w; 30     int next; 31 }de[M]; 32 double dis[Max]; 33 bool vis[Max]; 34  35 bool tested(Pleg v1,Point s,Point t){ 36     Pleg v2; v2.start=s; v2.end=t; 37     if(max(v1.start.x,v1.end.x)>=min(v2.start.x,v2.end.x)&& 38        max(v2.start.x,v2.end.x)>=min(v1.start.x,v1.end.x)&& 39        max(v1.start.y,v1.end.y)>=min(v2.start.y,v2.end.y)&& 40        multi(v2.start,v1.end,v1.start)*multi(v1.end,v2.end,v1.start)>0&& 41        multi(v1.start,v2.end,v2.start)*multi(v2.end,v1.end,v2.start)>0) 42        return false; 43        return true; 44 } 45  46 void addedge(int u,int v,double w){ 47     de[tot].u=u; 48     de[tot].v=v; 49     de[tot].w=w; 50     de[tot].next=head[u]; 51     head[u]=tot++; 52 } 53  54 void dijk(int s,int t){ 55     vis[s]=true; dis[s]=0; 56     for(int i=head[s];i!=-1;i=de[i].next){ 57         int v=de[i].v; 58         if(dis[v]>de[i].w) 59         dis[v]=de[i].w; 60     } 61     for(int i=0;i<=how_point;i++){ 62         int p=s; double min=inf; 63         for(int j=0;j<=how_point;j++){ 64             if(dis[j]<min&&!vis[j]){ 65                 min=dis[j]; p=j; 66             } 67         } 68         if(p==s) return ; 69         vis[p]=true; 70         for(int k=head[p];k!=-1;k=de[k].next){ 71             int v=de[k].v; 72             if(min+de[k].w<dis[v]&&!vis[v]){ 73                 dis[v]=min+de[k].w; 74             } 75         } 76     } 77 } 78  79 int main(){ 80     pot[0].x=0; pot[0].y=5; 81     int n; double a,b,c,d,e; Point tmp; 82     while(scanf("%d",&n)!=EOF){ 83         if(n==-1) break; 84         how_pleg=0;how_point=0; 85         memset(head,-1,sizeof(head)); tot=0; 86         memset(vis,false,sizeof(vis)); 87         for(int i=0;i<Max;i++) 88         dis[i]=inf; 89         for(int i=1;i<=n;i++){ 90             scanf("%lf%lf%lf%lf%lf",&a,&b,&c,&d,&e); 91             how_pleg++;    how_point++; 92             tmp.x=a; tmp.y=0; tmp.belong=how_pleg; 93             pot[how_point].x=a; pot[how_point].y=b; pot[how_point].belong=how_pleg; 94             edge[how_pleg].start=tmp; edge[how_pleg].end=pot[how_point]; 95             how_point++; how_pleg++; 96             pot[how_point].x=a; pot[how_point].y=c; pot[how_point].belong=how_pleg; 97             how_point++; 98             pot[how_point].x=a; pot[how_point].y=d; pot[how_point].belong=how_pleg; 99             edge[how_pleg].start=pot[how_point-1]; edge[how_pleg].end=pot[how_point];100             how_point++;  how_pleg++;101             pot[how_point].x=a; pot[how_point].y=e; pot[how_point].belong=how_pleg;102             tmp.x=a; tmp.y=10; tmp.belong=how_pleg;103             edge[how_pleg].start=pot[how_point]; edge[how_pleg].end=tmp;104         }105         how_point++;106         pot[how_point].x=10; pot[how_point].y=5;pot[how_point].belong=how_pleg+1;107         for(int i=0;i<=how_point;i++){108             for(int j=i+1;j<=how_point;j++){109                 int e=pot[j].belong;110                 bool flag=true;111                 for(int k=1;k<e;k++){112                     if(!tested(edge[k],pot[i],pot[j])){113                         flag=false;114                         break;115                     }116                 }117                 if(flag){118                     double x=pot[i].x-pot[j].x;119                     double y=pot[j].y-pot[i].y;120                     double d=sqrt(x*x+y*y);121                     addedge(i,j,d);122                 }123             }124         }125         dijk(0,how_point);126         printf("%0.2lf\n",dis[how_point]);127     }128 }
View Code