【bzoj1822】[JSOI2010] Frozen Nova 冷冻波

来源:互联网 发布:淘宝怎么加盟代理 编辑:程序博客网 时间:2024/04/27 18:07

  Circle的构造函数没赋初值都能过样例真是厉害啊……
  这题做法比较显然。巫师和精灵构成了二分图,第i个巫师能干的精灵个数就是Titime+1,判断所有精灵能否被干完的话跑个最大流就完事了。
  至于时间,显然具有单调性,于是二分之。
  没了。
  判断线段和圆相交的话另外写一篇文章好了。
  设网络流时间复杂度为O(F),则总时间复杂度为O((F+nm)logtime)
  网络流直接上了vani的模板。
  

#include <bits/stdc++.h>using namespace std;#define rep(i,a,b) for(int i=a,_=b;i<=_;i++)#define per(i,a,b) for(int i=a,_=b;i>=_;i--)#define For(i,a,b) for(int i=a,_=b;i< _;i++)#define maxn 203inline int rd() {    char c = getchar();    while (!isdigit(c) && c != '-') c = getchar() ; int x = 0 , f = 1;    if (c == '-') f = -1 ; else x = c - '0';    while (isdigit(c = getchar())) x = x * 10 + c - '0';    return x * f;}//===========================NetworkFlow===============const int NFmaxn = 3005;const int NFmaxm = 600005;const int NFinf = 0x7fffffff;struct NF_Line{  int to, next, v, opt;};struct Network_Flow{  NF_Line li[NFmaxm];  int be[NFmaxn], l, s, t, n, num[NFmaxn], note[NFmaxn];  void makeline(int fr, int to, int v)  {    ++l;    li[l].next = be[fr];    be[fr] = l;    li[l].to = to;    li[l].v = v;    li[l].opt = l + 1;    ++l;    li[l].next = be[to];    be[to] = l;    li[l].to = fr;    li[l].v = 0;    li[l].opt = l - 1;  }  void create(int N)  {    n = N;  }  int sap(int now, int maxf)  {    if (now == t) return maxf;    int mi = n, tot = 0;    for (int i = be[now]; i; i = li[i].next)    {      int to = li[i].to;      if (li[i].v && note[to] + 1 == note[now])      {        int k = sap(to, min(maxf - tot, li[i].v));        li[i].v -= k;        tot += k;        li[li[i].opt].v += k;        if (note[s] >= n || tot == maxf) return tot;      }      if (li[i].v) mi = min(mi, note[to]);    }    if (!tot)    {      if (!--num[note[now]])      {        note[s] = n;        return 0;      }      ++num[note[now] = mi + 1];    }    return tot;  }  int query(int S, int T)  {    s = S, t = T;    memset(num, 0, sizeof(num));    memset(note, 0, sizeof(note));    num[0] = n;    int ans = 0;    while (note[s] < n) ans += sap(s, NFinf);    return ans;  }  void clear()  {    l = s = t = n = 0;    memset(be, 0, sizeof(be));    memset(num, 0, sizeof(num));    memset(note, 0, sizeof(note));  }}SAP;//===========================NetworkFlow===============vector<int> rel[maxn];const int inf = 0x7fffffff;inline void upmin(int&a , int b) { if (a > b) a = b ; }inline void upmax(int&a , int b) { if (a < b) a = b ; }template<class T> inline T sqr(T x) { return x * x ; }struct Point {    int x , y;    Point(int x = 0 , int y = 0):x(x) , y(y) { }    friend Point operator-(Point a , Point b) { return Point(a.x - b.x , a.y - b.y) ; }    inline void print() { printf("%d %d\n" , x , y) ; }}b[maxn];struct Circle {    Point o;    int r;    Circle() { o = Point() , r = 0 ; }    Circle(Point o , int r):o(o) , r(r) { }    inline void print() { printf("%d " , r) , o.print() ; }}a[maxn] , c[maxn];struct Line {    Point a , b;    Line() { a = b = Point();}    Line(Point a , Point b):a(a) , b(b) {}};int n , m , K , mx , t[maxn];void input() {    n = rd() , m = rd() , K = rd();    rep (i , 1 , n) {        int x = rd() , y = rd() , r = rd();        t[i] = rd();        upmax(mx , t[i]);        a[i] = Circle(Point(x , y) , r);    }    rep (i , 1 , m) {        int x = rd() , y = rd();        b[i] = Point(x , y);    }    rep (i , 1 , K) {        int x = rd() , y = rd() , r = rd();        c[i] = Circle(Point(x , y) , r);    }}inline double cross(Point a , Point b) {    return a.x * b.y - a.y * b.x;}inline double dot(Point a , Point b) {    return a.x * b.x + a.y * b.y;}inline double DotToDotDis(Point a , Point b) {    return sqrt(sqr(a.x - b.x) + sqr(a.y - b.y));}inline double DotToSegDis(Point p , Line l) {    if (dot(l.a - p , l.b - p) > 0) return min(DotToDotDis(l.a , p) , DotToDotDis(l.b , p));    return fabs(cross(p - l.a , l.b - l.a)) / DotToDotDis(l.a , l.b);}inline bool ok(Circle a , Point b) {    if (DotToDotDis(a.o , b) > a.r) return 0;    rep (k , 1 , K)        if (DotToSegDis(c[k].o , Line(a.o , b)) < c[k].r) return 0;    return 1;}void GetIntersect() {    rep (i , 1 , n) rep (j , 1 , m) if (ok(a[i] , b[j]))        rel[i].push_back(j);}int check(int mid) {    SAP.clear();    SAP.create(n + m + 2);    rep (i , 1 , n) {        SAP.makeline(n + m + 1 , i , mid / t[i] + 1);        For (j , 0 , rel[i].size()) {            int x = rel[i][j];            SAP.makeline(i , x + n , 1);        }    }    rep (i , 1 , m) SAP.makeline(i + n , n + m + 2 , 1);    return SAP.query(n + m + 1 , n + m + 2);}void solve() {    GetIntersect();    int l = 0 , r = m * mx , ans = inf;    while (l <= r) {        int mid = (l + r) >> 1;        int cnt = check(mid);        if (cnt == m) upmin(ans , mid) , r = mid - 1;        else l = mid + 1;    }    printf("%d\n" , ans == inf ? -1 : ans);}int main() {    #ifndef ONLINE_JUDGE        freopen("data.txt" , "r" , stdin);    #endif    input();    solve();    return 0;}
0 0