• POJ 1556 The Doors


    线段求交+spfa.

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<cmath>
    #define maxn 1050
    #define eps 1e-8
    #define inf 0x3f3f3f3f
    using namespace std;
    struct point
    {
        double x,y;
        point(double x,double y):x(x),y(y) {}
        point() {}
        friend point operator -(point x,point y)
        {
            return point(x.x-y.x,x.y-y.y);
        }
        friend bool operator ==(point x,point y)
        {
            return ((x.x==y.x) && (x.y==y.y));
        }
    }p[maxn*50];
    struct line
    {
        point x,y,dt;
        line (point x,point y,point dt):x(x),y(y),dt(dt) {}
        line () {}
        friend double operator *(line x,line y)
        {
            return x.x.x*y.x.y-x.x.y*y.x.x;
        }
        friend bool operator ==(line x,line y)
        {
            return ((x.x==y.x) && (x.y==y.y));
        }
    }l[maxn*50];
    struct edge
    {
        int v,nxt;
        double w;
    }e[maxn*100];
    int n,g[maxn*50],tot1=0,tot2=0,nume=1;
    double x,a,b,c,d,dis[maxn*50];
    queue <int> q;
    bool vis[maxn*50];
    double dist(point x,point y) {return sqrt((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y));}
    void addedge(int u,int v,double w)
    {
        e[++nume].v=v;e[nume].w=w;
        e[nume].nxt=g[u];g[u]=nume;
    }
    point ask_cross(line x,line y)
    {
        double a,b,c,d,e,f;
        a=x.x.y-x.y.y;b=x.y.x-x.x.x;c=x.x.x*x.y.y-x.x.y*x.y.x;
        d=y.x.y-y.y.y;e=y.y.x-y.x.x;f=y.x.x*y.y.y-y.x.y*y.y.x;
        return point((b*f-c*e)/(a*e-b*d),(a*f-c*d)/(b*d-a*e));
    }
    bool isin(point x,line y)
    {
        point ret=x-y.x;
        if (!y.dt.x)
        {
            double mn=min(y.x.y,y.y.y),mx=max(y.x.y,y.y.y);
            return (x.y>mn && x.y<mx);
        }
        else return (ret.x/y.dt.x>0 && ret.x/y.dt.x<1);
    }
    bool check(point x,point y)
    {
        line now=line(x,y,y-x);
        for (int i=1;i<=tot2;i++)
        {
            if (fabs(now*l[i])<eps) continue;
            point cross=ask_cross(now,l[i]);
            if (isin(cross,l[i]) && isin(cross,now))
                return false;
        }
        return true;
    }
    void spfa()
    {
        while (!q.empty()) q.pop();memset(vis,false,sizeof(vis));
        for (int i=2;i<=tot1;i++) dis[i]=inf;
        dis[1]=0;vis[1]=true;q.push(1);
        while (!q.empty())
        {
            int head=q.front();q.pop();
            for (int i=g[head];i;i=e[i].nxt)
            {
                int v=e[i].v;
                if (dis[v]>dis[head]+e[i].w)
                {
                    dis[v]=dis[head]+e[i].w;
                    if (!vis[v]) {q.push(v);vis[v]=true;}
                }
            }
            vis[head]=false;
        }
    }
    int main()
    {
        for (;;)
        {
            memset(g,0,sizeof(g));nume=1;tot1=tot2=0;
            scanf("%d",&n);if (n==-1) break;
            p[++tot1]=point(0,5);
            for (int i=1;i<=n;i++)
            {
                scanf("%lf%lf%lf%lf%lf",&x,&a,&b,&c,&d);
                p[++tot1]=point(x,a);p[++tot1]=point(x,b);p[++tot1]=point(x,c);p[++tot1]=point(x,d);
                l[++tot2]=line(point(x,0),point(x,a),point(x,a)-point(x,0));
                l[++tot2]=line(point(x,b),point(x,c),point(x,c)-point(x,b));
                l[++tot2]=line(point(x,d),point(x,10),point(x,10)-point(x,d));
            }
            p[++tot1]=point(10,5);
            for (int i=1;i<=tot1;i++)
                for (int j=i+1;j<=tot1;j++)
                {
                    if (check(p[i],p[j]))
                    {
                        addedge(i,j,dist(p[i],p[j])); 
                        addedge(j,i,dist(p[i],p[j]));
                    }
                }
            spfa();
            printf("%.2f
    ",dis[tot1]);
        }
        return 0;
    }
  • 相关阅读:
    LeetCode 654. 最大二叉树
    LeetCode 617. 合并二叉树
    LeetCode 234. 回文链表
    LeetCode 328. 奇偶链表
    LeetCode 24. 两两交换链表中的节点
    LeetCode 21. 合并两个有序链表
    LeetCode 876. 链表的中间结点
    顺序表的定义及其相关基本操作
    LeetCode 206. 反转链表
    LeetCode 111. 二叉树的最小深度
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/6273257.html
Copyright © 2020-2023  润新知