zoukankan      html  css  js  c++  java
  • P4048 [JSOI2010]冷冻波

    传送门

    因为我数学太差,实在不会点到直线距离公式,只好叉积计算面积除以底来计算高了……

    简单来说就是两个向量((x1,y1),(x2,y2))的叉积为((x1y2-x2y1)),三角形ABC的向量(AB)(AC)的叉积的绝对值就是这个三角形面积的两倍

    这样的话枚举巫妖和精灵,然后看是不是有哪个圆的圆心到这条线的距离小于等于它的半径,是的话就有交点,gg了

    然后就是二分+网络流乱搞喽……每只巫妖向能打到的精灵连边,二分时间,然后从源点向巫妖连边,记得注意(0)秒的时候也可以发射就是了,所以每只巫妖能发射的总次数是总时间除以冷却再加一

    顺便一提我这个代码有点bug,因为有可能直线与圆相切,但切点不在线段上,这样的话巫妖能打到精灵,但按照上面的方法判断算是不行……所以我就改了改变成小于才不行然后A了……严格来说的话应该是用叉积判一下圆心到巫妖和精灵的两条线是否都在它与切点连线的同一侧的……实在懒了不想打……

    //minamoto
    #include<bits/stdc++.h>
    #define fp(i,a,b) for(register int i=a,I=b+1;i<I;++i)
    #define fd(i,a,b) for(register int i=a,I=b-1;i>I;--i)
    #define go(u) for(register int i=head[u],v=ver[i];i;i=Next[i],v=ver[i])
    #define inf 0x3f3f3f3f
    using namespace std;
    #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
    char buf[1<<21],*p1=buf,*p2=buf;
    int read(){
        int res,f=1;char ch;
        while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
        for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
        return res*f;
    }
    const int N=1005,M=5e5+5;
    int head[N],Next[M],ver[M],edge[M],tot=1;
    void add(int u,int v,int e){
        ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e;
        ver[++tot]=u,Next[tot]=head[v],head[v]=tot,edge[tot]=0;
    }
    int dep[N],cur[N],q[N],S,T;
    bool bfs(){
        int h=1,t=0;
        fp(i,S,T)cur[i]=head[i],dep[i]=-1;
        q[++t]=S,dep[S]=0;
        while(h<=t){
            int u=q[h++];
            go(u)if(dep[v]<0&&edge[i]){
                dep[v]=dep[u]+1,q[++t]=v;
                if(v==T)return true;
            }
        }return false;
    }
    int dfs(int u,int lim){
        if(u==T||!lim)return lim;
        int flow=0,f;
        for(int &i=cur[u];i;i=Next[i]){
            int v=ver[i];
            if(dep[v]==dep[u]+1&&(f=dfs(v,min(lim,edge[i])))){
                flow+=f,lim-=f;
                edge[i]-=f,edge[i^1]+=f;
                if(!lim)break;
            }
        }return flow;
    }
    int dinic(){int flow=0;while(bfs())flow+=dfs(S,inf);return flow;}
    struct node{int x,y,r,t;}p[N];
    int x[N],y[N],xx[N],yy[N],rr[N],vis[N],hh[N],n,m,k;
    inline double pow(double x){return x*x;}
    inline double dis(int i,int j){return sqrt(pow(p[i].x-x[j])+pow(p[i].y-y[j]));}
    bool check(int i,int j,int k){
        double cr=fabs((xx[k]-p[i].x)*(y[j]-p[i].y)-(x[j]-p[i].x)*(yy[k]-p[i].y));
        cr/=dis(i,j);return cr>=rr[k];
    }
    int res,l,r,mid,ans;
    bool ok(int mid){
        tot=res;for(register int i=2;i<=tot;i+=2)edge[i]+=edge[i^1],edge[i^1]=0;
        fp(i,S,T)head[i]=hh[i];
        fp(i,1,n)add(S,i,mid/p[i].t+1);
        return dinic()>=m;
    }
    int main(){
    //	freopen("frozen.in","r",stdin);
    //	freopen("frozen.out","w",stdout);
        n=read(),m=read(),k=read(),S=0,T=n+1+m;
        fp(i,1,n)p[i].x=read(),p[i].y=read(),p[i].r=read(),p[i].t=read();
        fp(i,1,m)x[i]=read(),y[i]=read();
        fp(i,1,k)xx[i]=read(),yy[i]=read(),rr[i]=read();
        fp(i,1,n)fp(j,1,m)if(dis(i,j)<=p[i].r){
            int flag=1;
            fp(l,1,k)if(!check(i,j,l)){flag=0;break;}
            if(flag)add(i,j+n,1),vis[j]=1;
        }fp(i,1,m)if(!vis[i])return puts("-1"),0;
        fp(i,1,m)add(i+n,T,1);
        fp(i,S,T)hh[i]=head[i];
        res=tot,l=0,r=4000000,mid,ans;
        while(l<=r){
            mid=(l+r)>>1;
            ok(mid)?(ans=mid,r=mid-1):(l=mid+1);
        }printf("%d
    ",ans);return 0;
    }
    
  • 相关阅读:
    Files 的值“
    unable to open databse file
    你选择的点它并不一定在线上!
    各图元对应的DXF名
    combobox下拉列表进行模糊查找时,容易导致光标隐藏
    autocad2010在进行加密时总是出问题
    AutoCAD2010中没有RibbonFoldPanel,需要用RibbonRowPanel替代
    cad2009中把我在2016中定义的块打开为匿名块
    VS2015 未加载程序集时不允许进行更改
    无法将类型为“System.Windows.Forms.SplitContainer”的对象强制转换为类型“System.ComponentModel.ISupportInitialize”
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/10004290.html
Copyright © 2011-2022 走看看