zoukankan      html  css  js  c++  java
  • POJ 1556 计算几何+最短路

     代码1:

    #include<iostream>
    #include<stdio.h>
    #include<string>
    #include<string.h>
    #include<algorithm>
    #include<map>
    #include<list>
    #include<set>
    #include<vector>
    #include<queue>
    #include<iomanip>
    #include<math.h>
    #define N 1050
    #define ST 1001
    #define EN 1002
    #define M 10000
    #define inf 1000000
    #define eps 1e-8
    #define ll long long
    using namespace std;
    inline ll Max(ll a,ll b){return a>b?a:b;}
    inline ll Min(ll a,ll b){return a<b?a:b;}
    struct Point{//点是2维的
    	double x,y;
    };
    struct v{
    	Point Start,End;
    };
    
    double Cross(Point p1,Point p2,Point p3,Point p4){//二维向量(p1p2)X(p3p4) 返回第三向量长度
    	double x1=p2.x-p1.x,y1=p2.y-p1.y;
    	double x2=p4.x-p3.x,y2=p4.y-p3.y;
    	return x1*y2-x2*y1;	//为0表示 p1p2 与p3p4共线
    	//直线:不为0就是相交
    }  
    double Cross_v(v v1,v v2){
    	return Cross(v1.Start,v1.End,v2.Start,v2.End);
    }
    double point_dis(Point p1,Point p2){
    	return sqrt((double)((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)));
    }
    bool On_Segment(Point p1,Point p2,Point p3){//p3点在 p1p2线段上
    	if(Cross(p1,p2,p1,p3)!=0)return false;
    	bool iny=(p1.y<=p3.y && p3.y<=p2.y)||(p1.y>=p3.y && p3.y>=p2.y);
    	bool inx=(p1.x<=p3.x && p3.x<=p2.x)||(p1.x>=p3.x && p3.x>=p2.x);
    	if(inx && iny)return true;
    	return false;
    }
    bool Segmentintersect(Point p1,Point p2,Point p3,Point p4){//p1p2 是否与 p3p4相交
    	double cross_1=Cross(p3,p4,p3,p1),cross_2=Cross(p3,p4,p3,p2);//cross_1 2必须一正一负且都不为0
    	double cross_3=Cross(p1,p2,p1,p3),cross_4=Cross(p1,p2,p1,p4);//cross_2 4必须一正一负且都不为0
    	//表示a线段 2点 在b线段 2侧
    	if(cross_1*cross_2<0 && cross_3*cross_4<0)return true;
    
    	//a线段端点在 b线段上 视情况取舍这种位置 
    //	if(cross_1==0 && On_Segment(p3,p4,p1))return true;
    //	if(cross_2==0 && On_Segment(p3,p4,p2))return true;
    //	if(cross_3==0 && On_Segment(p1,p2,p3))return true;
    //	if(cross_4==0 && On_Segment(p1,p2,p4))return true;
    	return false;
    }
    
    //----------------------- 2维计算几何模版-------------------------------------
    struct Edge{
    	int f,t,nex;
    	double w;
    }edge[M];
    int head[N],edgenum;
    int n;
    void addedge(int u,int v,double w){
    	Edge E={u,v,head[u],w};
    	edge[edgenum]=E;
    	head[u]=edgenum++;
    }
    
    double dis[N];
    void spfa(int s,int e){
    	queue<int>q; 
    	bool vis[N]; memset(vis,0,sizeof(vis));
    	int i,u,v;
    	for(i=0;i<N;i++)dis[i]=inf;
    	dis[s]=0;	vis[s]=true;
    	q.push(s);
    	while(!q.empty()){
    		u=q.front(); q.pop();
    		for(i=head[u];i!=-1;i=edge[i].nex)
    		{
    			v=edge[i].t;
    			if(dis[v]>dis[u]+edge[i].w){
    				dis[v]=dis[u]+edge[i].w;
    				if(!vis[v])q.push(v);
    			}
    		}
    
    	}
    }
    Point line[N][4],Start,End;
    Point Seg[N][6];
    int main()
    {
    	int i,j;
    	Start.x=0,Start.y=5;
    	End.x=10,End.y=5;
    
    	while(scanf("%d",&n),n>=0)
    	{
    		for(i=0;i<n;i++){
    			double x,y1,y2,y3,y4;
    			scanf("%lf %lf%lf %lf%lf",&x,&y1,&y2,&y3,&y4);
    			line[i][0].x=line[i][1].x=line[i][2].x=line[i][3].x=x;
    			line[i][0].y=y1;
    			line[i][1].y=y2;
    			line[i][2].y=y3;
    			line[i][3].y=y4;
    
    			Seg[i][0].x=x,Seg[i][0].y=0;
    			for(j=1;j<=4;j++)Seg[i][j]=line[i][j-1];
    			Seg[i][5].x=x,Seg[i][5].y=10;
    
    		}
    		memset(head,-1,sizeof(head));	edgenum=0;
    		for(i=0;i<n-1;i++)
    			for(j=i+1;j<n;j++)
    
    				for(int ii=0;ii<4;ii++)
    					for(int jj=0;jj<4;jj++)
    					{
    						bool can=true;
    						for(int k=i+1;k<j && can;k++)
    							for(int kk=0;kk<5 &&can;kk+=2)
    								if(Segmentintersect(line[i][ii],line[j][jj],Seg[k][kk],Seg[k][kk+1]))
    									can=false;
    
    						if(can)addedge(i*10+ii,j*10+jj,point_dis(line[i][ii],line[j][jj]));
    					}
    
    					for(i=0;i<n;i++)
    						for(int ii=0;ii<4;ii++)
    						{
    							bool cans=true,cane=true;
    							for(int k=0;k<i && cans;k++)
    								for(int kk=0;kk<5 &&cans;kk+=2)
    									if(Segmentintersect(Start,line[i][ii],Seg[k][kk],Seg[k][kk+1]))
    										cans=false;
    
    							if(cans)addedge(ST,i*10+ii,point_dis(Start,line[i][ii]));
    
    							for(int k=i+1;k<n && cane;k++)
    								for(int kk=0;kk<5 &&cane;kk+=2)
    									if(Segmentintersect(End,line[i][ii],Seg[k][kk],Seg[k][kk+1]))
    										cane=false;
    
    							if(cane)addedge(i*10+ii,EN,point_dis(End,line[i][ii]));
    						}
    
    						bool canse=true;
    						for(int k=0;k<n && canse;k++)
    							for(int kk=0;kk<5 &&canse;kk+=2)
    								if(Segmentintersect(Start,End,Seg[k][kk],Seg[k][kk+1]))
    									canse=false;
    						if(canse)addedge(ST,EN,point_dis(Start,End));
    
    						spfa(ST,EN);
    						printf("%.2lf
    ",dis[EN]);
    	}
    	return 0;
    }
    /*
    1
    5 4 6 7 8
    2
    4 2 7 8 9
    7 3 4.5 6 7
    
    */
    
    
    
    


     

    代码2:

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<string>
    #include<math.h>
    #include<algorithm>
    #include<stdlib.h>
    #include<ctype.h>
    #include<iomanip>
    #include<set>
    #include<map>
    #include<list>
    #include<vector>
    #include<queue>
    #include<stack>
    using namespace std;
    const double pi=acos(-1.0);
    const double eps = 1e-8;
    int sgn(double x)
    {
        if(fabs(x) < eps)return 0;
        if(x < 0)return -1;
        else return 1;
    }
    struct Point
    {
        double x,y;
        Point(){}
        Point(double _x,double _y)
        {
            x = _x;y = _y;
        }
        Point operator -(const Point &b)const
        {
            return Point(x - b.x,y - b.y);
        }
        double operator ^(const Point &b)const
        {
            return x*b.y - y*b.x;
        }
        double operator *(const Point &b)const
        {
            return x*b.x + y*b.y;
        }
        void transXY(double B)
        {
            double tx = x,ty = y;
            x = tx*cos(B) - ty*sin(B);
            y = tx*sin(B) + ty*cos(B);
        }
    };
    double dis(Point a,Point b)
    {
            double ss=a.x-b.x;
            double tt=a.y-b.y;
            return sqrt(ss*ss+tt*tt);
    }
    struct Line
    {
        Point s,e;
        double k;
        Line(){}
        Line(Point _s,Point _e)
        {
            s = _s;e = _e;
            k = atan2(e.y - s.y,e.x - s.x);
        }
        pair<int,Point> operator &(const Line &b)const
        {
            Point res = s;
            if(sgn((s-e)^(b.s-b.e)) == 0)
            {
                if(sgn((s-b.e)^(b.s-b.e)) == 0)
                    return make_pair(0,res);
                else return make_pair(1,res);
            }
            double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));
            res.x += (e.x-s.x)*t;
            res.y += (e.y-s.y)*t;
            return make_pair(2,res);
        }
    };
    bool inter(Line l1,Line l2)
    {
        return
            max(l1.s.x,l1.e.x) >= min(l2.s.x,l2.e.x) &&
            max(l2.s.x,l2.e.x) >= min(l1.s.x,l1.e.x) &&
            max(l1.s.y,l1.e.y) >= min(l2.s.y,l2.e.y) &&
            max(l2.s.y,l2.e.y) >= min(l1.s.y,l1.e.y) &&
            sgn((l2.s-l1.s)^(l1.e-l1.s))*sgn((l2.e-l1.s)^(l1.e-l1.s)) <= 0 &&
            sgn((l1.s-l2.s)^(l2.e-l1.s))*sgn((l1.e-l2.s)^(l2.e-l2.s)) <= 0;
    }
    struct NODE
    {
            double x,y1,y2,y3,y4;
    }pp[2000];
    bool cmp(NODE a,NODE b)
    {
            return a.x<b.x;
    }
    #define inf 10000000
    const int maxn=300010;
    int head[maxn],tol,m,n;
    double dist[maxn];
    struct Edge
    {
            int to,next;
            double val;
    }edge[10*maxn];
    void add(int u,int v,double w)
    {
            edge[tol].to=v;
            edge[tol].next=head[u];
            edge[tol].val=w;
            head[u]=tol++;
    }
    struct Node
    {
            int id;
            double dist;
            Node(int a=0,double b=0):id(a),dist(b){}
            bool operator < (const Node &b) const
            {
                    return dist>b.dist;
            }
    };
    void fun(int st)
    {
            int i,j,u,v;
            priority_queue<Node> q;
            q.push(Node(st,0));
            for(i=1;i<=n;i++)dist[i]=inf;
            dist[st]=0;
            while(!q.empty())
            {
                    Node ret=q.top();q.pop();
                    u=ret.id;
                    if(dist[u]<ret.dist)continue;
                    for(i=head[u];i!=-1;i=edge[i].next)
                    {
                            v=edge[i].to;
                            if(dist[v]>dist[u]+edge[i].val)
                            {
                                    dist[v]=dist[u]+edge[i].val;
                                    q.push(Node(v,dist[v]));
                            }
                    }
            }
    }
    Line s1[500];
    Point s2[500];
    int main()
    {
            int i,j,k,m;
            while(~scanf("%d",&m))
            {
                    if(m==-1)break;
                    for(i=1;i<=m;i++)scanf("%lf%lf%lf%lf%lf",&pp[i].x,&pp[i].y1,&pp[i].y2,&pp[i].y3,&pp[i].y4);
                    sort(pp+1,pp+m+1,cmp);
                    memset(head,-1,sizeof(head));tol=0;n=0;
                    int indexx=0;
                    s2[++n]=Point(0,5);
                    for(i=1;i<=m;i++)
                    {
                          Point p1,p2,p3,p4,p5,p6;
                          p1=Point(pp[i].x,0.0);
                          s2[++n]=p1;
                          p2=Point(pp[i].x,pp[i].y1);
                           s2[++n]=p2;
                          p3=Point(pp[i].x,pp[i].y2);
                          s2[++n]=p3;
                          p4=Point(pp[i].x,pp[i].y3);
                          s2[++n]=p4;
                          p5=Point(pp[i].x,pp[i].y4);
                          s2[++n]=p5;
                          p6=Point(pp[i].x,10.0);
                          s2[++n]=p6;
                          s1[++indexx]=Line(p1,p2);
                          s1[++indexx]=Line(p3,p4);
                          s1[++indexx]=Line(p5,p6);
                    }
                    s2[++n]=Point(10,5);
                    for(i=1;i<=n;i++)
                    {
                            for(j=i+1;j<=n;j++)
                            {
                                 if(sgn(s2[i].x-s2[j].x)==0)continue;
                                 Line s(s2[i],s2[j]);
                                 int flag=1;
                                 for(k=1;k<=indexx;k++)
                                 {
                                         if(sgn(s1[k].s.x-s2[i].x)==0)continue;
                                         if(sgn(s1[k].s.x-s2[j].x)==0)continue;
                                         if(inter(s1[k],s))
                                         {
                                               flag=0;
                                               break;
                                         }
                                 }
                                 if(flag) add(i,j,dis(s2[i],s2[j]));
                            }
                    }
                    fun(1);
                    printf("%.2f
    ",dist[n]);
            }
            return 0;
    }
    


     

  • 相关阅读:
    ajax技术
    JSDOM获取子节点的一些方法
    防止a标签跳转的几种方法
    关于childNodes和children
    三种预览图片的方法
    异步加载js文件的方法
    跨域访问的解决方案
    关于在JS中设置标签属性
    Eclipse导入web项目发布项目时报Tomcat version 7.0 only supports J2EE 1.2, 1.3, 1.4, and Java EE 5 and 6 Web错误解决方案
    Maven构建项目报No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK? 问题的解决方案
  • 原文地址:https://www.cnblogs.com/suncoolcat/p/3331163.html
Copyright © 2011-2022 走看看