zoukankan      html  css  js  c++  java
  • 1368. 燃烧木棍

    Description

    Solution

    根据木棍的长度只有 \(1\)\(\sqrt{2}\) 可知,若两根木棍相交,则一定交在中点。

    那我们先将所有点的坐标变成两倍,时间也变成两倍,然后对于长度为 \(\sqrt{2}\) 的木棍,取中点,向两个端点连长度为 \(t\)(因为是\(\frac{2t}{2}\)) 的边。长度为 \(1\) 的木棍就直接将两个端点连起来,长度为 \(2t\)

    然后跑 \(\mathrm{Floyd}\)。枚举每个点作为起点(注意不要枚举新增的中点),求出其到最远的点的燃烧时间。但在这个时间内可能有些边没烧完。所以再遍历所有边,找出需要额外时间最多的边,加入答案。

    最后将答案除以 2,因为之前将时间变成了两倍。

    Code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define N 50
    #define X 805
    #define db double
    using namespace std;
    struct node
    {
        int t,x1,y1,x2,y2,typ;
    }edg[N];
    struct edge
    {
        int x,y,v;
    }a[N<<2];
    int n,x1,x2,y1,y2,t,cnt,tot,sum1,sum2,id[X][X],dis[N<<2][N<<2];
    db ans;
    bool bj[N][N];
    void add(int x,int y,int z)
    {
        a[++tot].x=x;
        a[tot].y=y;
        a[tot].v=z;
        dis[x][y]=z;
    }
    int main()
    {
        freopen("fire.in","r",stdin);
        freopen("fire.out","w",stdout);
        scanf("%d",&n);
        for (int i=1;i<=n;++i)
        {
            scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&t);
            x1*=2;y1*=2;x2*=2;y2*=2;t*=2;
            x1+=400;x2+=400;y1+=400;y2+=400;
            if (!id[x1][y1]) id[x1][y1]=++cnt;
            if (!id[x2][y2]) id[x2][y2]=++cnt;
            edg[i].t=t;
            edg[i].x1=x1;edg[i].y1=y1;edg[i].x2=x2;edg[i].y2=y2;
            if (x1==x2||y1==y2) edg[i].typ=1;
            else edg[i].typ=2;
            bj[id[x1][y1]][id[x2][y2]]=bj[id[x2][y2]][id[x1][y1]]=true;
        }
        memset(dis,0x3f3f3f3f,sizeof(dis));
        for (int i=1;i<=n;++i)
        {
            x1=edg[i].x1;y1=edg[i].y1;
            x2=edg[i].x2;y2=edg[i].y2;
            t=edg[i].t;
            if (edg[i].typ==1) add(id[x1][y1],id[x2][y2],t),add(id[x2][y2],id[x1][y1],t);
            else
            {
                if (x1>x2) swap(x1,x2),swap(y1,y2);
                if (id[x1][y2]&&id[x2][y1]&&bj[id[x1][y2]][id[x2][y1]])
                {
                    int x=(x1+x2)/2,y=(y1+y2)/2;
                    if (!id[x][y]) id[x][y]=++cnt;
                    add(id[x1][y1],id[x][y],t/2);
                    add(id[x][y],id[x1][y1],t/2);
                    add(id[x][y],id[x2][y2],t/2);
                    add(id[x2][y2],id[x][y],t/2);
                }
                else
                {
                    add(id[x1][y1],id[x2][y2],t);
                    add(id[x2][y2],id[x1][y1],t);
                }
            }
        }
        for (int i=1;i<=cnt;++i)
            dis[i][i]=0;
        for (int k=1;k<=cnt;++k)
            for (int i=1;i<=cnt;++i)
                for (int j=1;j<=cnt;++j)
                    if (i!=j&&i!=k&&j!=k)
                        dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
        ans=2147483647.0;
        for (int i=1;i<=n;++i)
        {
            sum1=sum2=0;
            for (int j=1;j<=cnt;++j)
                sum1=max(sum1,dis[i][j]);
            for (int j=1;j<=tot;++j)
            {
                int x=a[j].x,y=a[j].y,v=a[j].v;
                int c=sum1-dis[i][x]+sum1-dis[i][y];
                if (c>=v) continue;
                sum2=max(sum2,v-c);
            }
            ans=min(ans,(db)((sum1+sum2/2.0)/2.0));
        }
        printf("%.4lf\n",ans);
        return 0;
    }
    
  • 相关阅读:
    Vue框架构造
    JavaScript-改变this指向
    前端发展史
    python篇第10天【For 循环语句】
    python篇第10天【While 循环语句】
    python篇第8天【运算符】
    python篇第6天【数据类型】
    python篇第5天【变量】
    Python篇函数总结【输出函数】
    python篇第3天【编码规范】
  • 原文地址:https://www.cnblogs.com/Livingston/p/15807888.html
Copyright © 2011-2022 走看看