首页 > 代码库 > BZOJ 1822 Frozen Nova 冷冻波(最大流)

BZOJ 1822 Frozen Nova 冷冻波(最大流)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1822

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

思路:预处理每个巫妖可以杀死的精灵。之后 二分答案最大流判可行性。但是我觉得这个数据有问题。下面这个预处理是用的别人的。我原来写的是WA。但是我觉得这个预处理是有bug的。他是直接相当于 求树到巫妖和精灵连线的距离小于树的半径。但是我觉得这个不对的。比如巫妖和精灵在树的同一侧。

 

struct node{    int v,cap,next;};  node edges[N*N];int head[N],e;  void add(int u,int v,int cap){    edges[e].v=v;    edges[e].cap=cap;    edges[e].next=head[u];    head[u]=e++;}  void Add(int u,int v,int cap){    add(u,v,cap);    add(v,u,0);}  int cur[N],h[N],num[N],pre[N];  int Maxflow(int s,int t,int n){    int i;    for(i=0;i<=n;i++) h[i]=num[i]=0,cur[i]=head[i];    int u=s,ans=0,Min,k,x;    while(h[u]<n)    {        if(u==t)        {            Min=INF+1;            for(i=s;i!=t;i=edges[cur[i]].v)            {                x=cur[i];                if(edges[x].cap<Min) Min=edges[x].cap,k=i;            }            ans+=Min; u=k;            for(i=s;i!=t;i=edges[cur[i]].v)            {                x=cur[i];                edges[x].cap-=Min;                edges[x^1].cap+=Min;            }        }        for(i=cur[u];i!=-1;i=edges[i].next)        {            if(edges[i].cap>0&&h[u]==1+h[edges[i].v])            {                break;            }        }        if(i!=-1)        {            cur[u]=i;            pre[edges[i].v]=u;            u=edges[i].v;        }        else        {            if(--num[h[u]]==0) break;            cur[u]=head[u];            x=n;            for(i=head[u];i!=-1;i=edges[i].next)            {                k=edges[i].v;                if(edges[i].cap>0&&h[k]<x) x=h[k];             }            h[u]=x+1;            num[x+1]++;            if(u!=s) u=pre[u];        }    }    return ans;}  struct A{    int x,y,r,t;         void get()    {        RD(x,y); RD(r,t);    }}; A a[N]; struct B{    int x,y;    void get()    {        RD(x,y);    } }; B b[N]; struct C{    int x,y,r;         void get()    {        RD(x,y,r);    }}; C c[N]; int n,m,K;vector<int> V[N]; int dis(int x,int y){    return x*x+y*y;}  int check(A pa,B pb,C pc){    double a=sqrt(dis(pa.x-pb.x,pa.y-pb.y)*1.0);    double b=sqrt(dis(pc.x-pb.x,pc.y-pb.y)*1.0);    double c=sqrt(dis(pa.x-pc.x,pa.y-pc.y)*1.0);    double p=(a+b+c)/2;    double s=sqrt(p*(p-a)*(p-b)*(p-c));    double tmp=a*pc.r/2;    if(tmp>=s) return 0;    return 1;}  void init(){    int i,j,k;    FOR1(i,n) FOR1(j,m)    {        if(dis(a[i].x-b[j].x,a[i].y-b[j].y)>a[i].r*a[i].r) continue;        FOR1(k,K) if(!check(a[i],b[j],c[k])) break;        if(k>K) V[i].pb(j);    }}int OK(int mid){    clr(head,-1); e=0;    int s=0,t=n+m+1,i,j,k;    FOR1(i,n) Add(s,i,mid/a[i].t+1);    FOR1(i,m) Add(n+i,t,1);    FOR1(i,n) FOR0(j,SZ(V[i]))    {        k=V[i][j];        Add(i,n+k,1);    }    return Maxflow(s,t,t+1)==m;}  int main(){    RD(n,m,K);    int i,j;    FOR1(i,n) a[i].get();    FOR1(i,m) b[i].get();    FOR1(i,K) c[i].get();    init();    int low=0,high=INF,mid,ans=-1;    while(low<=high)    {        mid=(low+high)>>1;        if(OK(mid)) ans=mid,high=mid-1;        else low=mid+1;    }    PR(ans);}