zoukankan      html  css  js  c++  java
  • bzoj 1822 冷冻波

    题目大意:

    在游戏中,巫妖是一种强大的英雄,它的技能Frozen Nova每次可以杀死一个小精灵

    我们认为,巫妖和小精灵都可以看成是平面上的点。

    当巫妖和小精灵之间的直线距离不超过R,且巫妖和小精灵的连线与任何树木都没有公共点,巫妖就可以瞬间杀灭一个小精灵。

    在森林里有N个巫妖,每个巫妖释放Frozen Nova之后,都需要等待一段时间,才能再次施放

    不同的巫妖有不同的等待时间和施法范围,但相同的是,每次施放都可以杀死一个小精灵。

    若从0时刻开始计算,至少需要花费多少时间,可以杀死所有的小精灵

    思路:

    最大流建图还是比较好想的

    但是答案需要二分,然后用最大流判断

    连边的时候每个巫妖和它可以消灭的小精灵连一条流量为一的边

    每个小精灵和超级汇连一条流量为1的边

    每个巫妖和超级源连一条时间(二分得到)/冷却时间+1的流量的边

    但是如何判断哪些巫妖和小精灵之间连边呢

    需要计(jie)算(xi)几何判断

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cstdlib>
      5 #include<cmath>
      6 #include<algorithm>
      7 #include<queue>
      8 #include<vector>
      9 #include<map>
     10 #define inf 2139062143
     11 #define ll long long
     12 #define MAXN 420
     13 using namespace std;
     14 inline int read()
     15 {
     16     int x=0,f=1;char ch=getchar();
     17     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
     18     while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
     19     return x*f;
     20 }
     21 int n,m,k,r[MAXN],cd[MAXN],R[MAXN],d[MAXN];
     22 struct node {int x,y;}g[MAXN],h[MAXN],tr[MAXN];
     23 double dis(int x1,int y1,int x2,int y2) {return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}
     24 int check(node a,node b,int i)
     25 {
     26     if(dis(a.x,a.y,b.x,b.y)>=r[i]) return 0;
     27     int A=b.y-a.y,B=a.x-b.x,C=b.x*a.y-a.x*b.y;
     28     for(int l=1;l<=k;l++)
     29     {
     30         double dst=fabs(A*tr[l].x+B*tr[l].y+C)/sqrt(A*A+B*B);
     31         double k1,b1,b2,b3;
     32         if(a.x==b.x) b1=a.y,b2=b.y,b3=tr[l].y;
     33         else if(a.y==b.y) b1=a.x,b2=b.x,b3=tr[l].x;
     34         else k1=B/A,b1=a.y-k1*a.x,b2=b.y-k1*b.x,b3=tr[l].y-k1*tr[l].x;
     35         if((b3-b1)*(b3-b2)<=0)  if(dst<=R[l]) return 0;
     36         if(abs(b3-b1)>abs(b3-b2)) if(dis(b.x,b.y,tr[l].x,tr[l].y)<=R[l]) return 0;
     37         else if(dis(a.x,a.y,tr[l].x,tr[l].y)<=R[l]) return 0;
     38     }
     39     return 1;
     40 }
     41 struct dinic 
     42 {
     43     int fst[MAXN],nxt[MAXN*MAXN],to[MAXN*MAXN],val[MAXN*MAXN],mp[MAXN][MAXN],cnt,s,t;
     44     void mem() {memset(fst,0xff,sizeof(fst));cnt=-1;}
     45     void add(int u,int v,int w) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v,val[cnt]=w;}
     46     void build(int x)
     47     {
     48         mem();
     49         for(int i=1;i<=n;i++) {add(s,i,x/cd[i]+1);add(i,s,0);}
     50         for(int i=1;i<=m;i++) {add(n+i,t,1);add(t,n+i,0);}
     51         for(int i=1;i<=n;i++)
     52             for(int j=1;j<=m;j++)
     53                 if(mp[i][j]) {add(i,n+j,1);add(n+j,i,0);}
     54     }
     55     int vis[MAXN],tot,cur[MAXN],dep[MAXN],q[MAXN];
     56     int bfs()
     57     {
     58         int l=1,r=0;
     59         memset(dep,0xff,sizeof(dep));
     60         vis[t]=++tot,q[++r]=t;
     61         while(l<=r)
     62         {
     63             int x=q[l++];
     64             for(int i=fst[x];i!=-1;i=nxt[i])
     65                 if(val[i^1]&&vis[to[i]]!=tot) 
     66                 {
     67                     vis[to[i]]=tot,dep[to[i]]=dep[x]+1,q[++r]=to[i];
     68                     if(to[i]==s) return 1;
     69                 }
     70         }
     71         return vis[s]==tot;
     72     }
     73     int dfs(int x,int a)
     74     {
     75         if(x==t||!a) return a;
     76         int flow=0,f;
     77         for(int& i=cur[x];i!=-1;i=nxt[i])
     78         {
     79             if(val[i]&&dep[to[i]]==dep[x]-1&&(f=dfs(to[i],min(a,val[i]))))
     80             {
     81                 val[i]-=f,val[i^1]+=f,flow+=f,a-=f;
     82                 if(!a) break;
     83             }
     84         }
     85         return flow;
     86     }
     87     int solve()
     88     {
     89         int ans=0;int f;
     90         while(bfs())
     91         {
     92             for(int i=0;i<=n+m+1;i++) cur[i]=fst[i];
     93             while(f=dfs(s,inf)) ans+=f;
     94         }
     95         return ans;
     96     }
     97 }D;
     98 int main()
     99 {
    100     n=read(),m=read(),k=read();int mx=-1;
    101     for(int i=1;i<=n;i++) g[i].x=read(),g[i].y=read(),r[i]=read(),cd[i]=read(),mx=max(mx,cd[i]);
    102     for(int i=1;i<=m;i++) {h[i].x=read(),h[i].y=read();D.add(n+i,n+m+2,1);D.add(n+m+2,n+i,0);}
    103     for(int i=1;i<=k;i++) tr[i].x=read(),tr[i].y=read(),R[i]=read();
    104     D.s=0,D.t=n+m+1;int f;
    105     for(int j=1;j<=m;j++)
    106     {
    107         f=0;
    108         for(int i=1;i<=n;i++)
    109         {
    110             D.mp[i][j]=check(g[i],h[j],i);
    111             if(D.mp[i][j]) f=1;
    112         }
    113         if(!f) {puts("-1");return 0;}
    114     }
    115     int l=0,r=m*mx,mid;
    116     int ans=inf;
    117     while(l<=r)
    118     {
    119         mid=(l+r)>>1;
    120         D.build(mid);
    121         if(D.solve()==m) ans=min(ans,mid),r=mid-1;
    122         else l=mid+1;
    123     }
    124     printf("%d",ans);
    125 }
    View Code

    对于计算几何非常不熟练,只能用解析几何

    写完的时候因为忘记了有n+m+2个点调了好久以及循环的时候把循环的变量写没了

  • 相关阅读:
    个人管理:2,3月微薄整理
    ORM相关图片整理
    LmgORM项目 实体类转换器
    (转)Enterprise Architect 7.0入门教程
    禁止右键复制的代码
    UML示例图(转)学习
    Flash FMS Helloword
    模拟生成Guid
    Flash Media Server安装
    WebSphere创建删除概要文件
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/8409328.html
Copyright © 2011-2022 走看看