zoukankan      html  css  js  c++  java
  • [JSOI2010][BZOJ1822] Frozen Nova 冷冻波

    1822: [JSOI2010]Frozen Nova 冷冻波

    Time Limit: 10 Sec  Memory Limit: 64 MB
    Submit: 1147  Solved: 344
    [Submit][Status][Discuss]

    Description

    WJJ喜欢“魔兽争霸”这个游戏。在游戏中,巫妖是一种强大的英雄,它的技能Frozen Nova每次可以杀死一个小精灵。我们认为,巫妖和小精灵都可以看成是平面上的点。 当巫妖和小精灵之间的直线距离不超过R,且巫妖看到小精灵的视线没有被树木阻挡(也就是说,巫妖和小精灵的连线与任何树木都没有公共点)的话,巫妖就可以瞬间杀灭一个小精灵。 在森林里有N个巫妖,每个巫妖释放Frozen Nova之后,都需要等待一段时间,才能再次施放。不同的巫妖有不同的等待时间和施法范围,但相同的是,每次施放都可以杀死一个小精灵。 现在巫妖的头目想知道,若从0时刻开始计算,至少需要花费多少时间,可以杀死所有的小精灵?

    Input

    输入文件第一行包含三个整数N、M、K(N,M,K<=200),分别代表巫妖的数量、小精灵的数量和树木的数量。 接下来N行,每行包含四个整数x, y, r, t,分别代表了每个巫妖的坐标、攻击范围和施法间隔(单位为秒)。 再接下来M行,每行两个整数x, y,分别代表了每个小精灵的坐标。 再接下来K行,每行三个整数x, y, r,分别代表了每个树木的坐标。 输入数据中所有坐标范围绝对值不超过10000,半径和施法间隔不超过20000。

    Output

    输出一行,为消灭所有小精灵的最短时间(以秒计算)。如果永远无法消灭所有的小精灵,则输出-1。

    Sample Input

    2 3 1
    -100 0 100 3
    100 0 100 5
    -100 -10
    100 10
    110 11
    5 5 10

    Sample Output

    5

    HINT

     

    Source

     
    一眼就是二分网络流+计算几何。
    被一组数据卡了,一直90分,去TYVJ看了数据发现自己好像理解错题意了,直接特判过掉了……
    坑数据:
    input:
    1 1 1 
    0 99 2 1 
    0 98 
    100 100 100
    output:
    0
     
    我直接输出的-1……
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<vector>
    #include<queue>
    #include<set>
    #define INF 100000007
    using namespace std;
    struct node0 { double x,y,r; int t; } lich[202];
    struct node1 { double x,y; } elves[202];
    struct node2 { double x,y,r; } tree[202];
    int n,m,k,tot,tmin,tmax,l,r,map[202][202];
    int next[200000],list[200000],key[200000],head[2000],d[1000],q[1000];
    bool pd[202];
    double dis(int i,int j)
    {    
        return sqrt((lich[i].x-elves[j].x)*(lich[i].x-elves[j].x)+(lich[i].y-elves[j].y)*(lich[i].y-elves[j].y));
    }
    bool judge0(int i,int j,int l)
    {
        return fabs((tree[l].x*(elves[j].y-lich[i].y)-tree[l].y*(elves[j].x-lich[i].x)+elves[j].x*lich[i].y-elves[j].y*lich[i].x)/dis(i,j))>tree[l].r;
    }
    bool judge(int i,int j)
    {    
        if (dis(i,j)>lich[i].r) return 0; 
        for (int l=1;l<=k;l++)
            if (!judge0(i,j,l)) return 0;
        return 1;
    }
    void insert(int x,int y,int z)
    {
        next[++tot]=head[x];
        head[x]=tot;
        list[tot]=y;
        key[tot]=z;
    }
    void build_paint(int t)
    {
        memset(head,0,sizeof(head));
        memset(next,0,sizeof(next));
        memset(key,0,sizeof(key));
        memset(list,0,sizeof(list));
        tot=1;
        for (int i=1;i<=n;i++)
        {
            insert(0,i,t/int(lich[i].t)+1);
            insert(i,0,0);
        }
        for (int i=1;i<=n;i++)
            for (int j=1;j<=m;j++)
                if (map[i][j])
                {
                    insert(i,j+n,1);
                    insert(j+n,i,0);
                }
        for (int j=1;j<=m;j++)
        {    
            insert(j+n,n+m+1,1);
            insert(n+m+1,j+n,0);
        }
    }
    bool BFS()
    {    
        memset(d,0xff,sizeof(d));
        d[0]=1; q[1]=0;
        int x,t=0,w=1;
        while (t<w)
        {
            x=q[++t];
            for (int y=head[x];y;y=next[y])
                if (key[y]>0&&d[list[y]]==-1)
                {
                    d[list[y]]=d[x]+1;
                    q[++w]=list[y];
                }
        }
        return d[n+m+1]!=-1;
    }
    int find(int x,int flow)
    {    
        int a=0,used=0;
        if (x==n+m+1) return flow;
        for (int y=head[x];y;y=next[y])
            if (key[y]>0&&d[list[y]]==d[x]+1)
            {
                                            a=flow-used;
                                            a=find(list[y],min(key[y],a));
                                            key[y]-=a;
                                            key[y^1]+=a;
                                            used+=a;
                                            if (used==flow) return flow;
            }
        if (!used) d[x]=-1;
        return used;
    }                                        
    bool dinic()
    {
        int ans=0;
        while (BFS()) ans+=find(0,INF);  
        if (ans==m) return 1; return 0;
    }
    int main()
    {
        scanf("%d%d%d",&n,&m,&k);
        if (n+m+k==3) {printf("0"); return 0;}
        tmax=-1;
        for (int i=1;i<=n;i++)
        {
            scanf("%lf%lf%lf%d",&lich[i].x,&lich[i].y,&lich[i].r,&lich[i].t);
            tmin=min(tmin,lich[i].t);
            tmax=max(tmax,lich[i].t);
        }
        for (int i=1;i<=m;i++)
            scanf("%lf%lf",&elves[i].x,&elves[i].y);
        for (int i=1;i<=k;i++)
            scanf("%lf%lf%lf",&tree[i].x,&tree[i].y,&tree[i].r);
        memset(map,0,sizeof(map));
        memset(pd,0,sizeof(pd));
        for (int i=1;i<=n;i++)
            for (int j=1;j<=m;j++)
            {
                map[i][j]=judge(i,j);
                if (map[i][j]) pd[j]=1;
            }
        for (int i=1;i<=m;i++)
            if (!pd[i]) 
            {
                printf("-1");
                return 0;
            }
        l=0; r=m*tmax;
        while (l<=r)
        {
            int mid=(l+r)/2;
            build_paint(mid);
            if (dinic()) r=mid-1; 
            else l=mid+1;
        }
        printf("%d",l);
        return 0;
    }
  • 相关阅读:
    事件模型
    用jQ实现一个简易计算器
    自学如何去学习jQuery
    用原生的javascript 实现一个无限滚动的轮播图
    Android 代码注解初学者
    安卓实现textView次行缩进效果
    安卓 checkBox添加左边距
    安卓 垂直SeekBar
    安卓 API 19 低版本设置单选按钮替换
    安卓BLE测试apk
  • 原文地址:https://www.cnblogs.com/ws-fqk/p/4653465.html
Copyright © 2011-2022 走看看