【bzoj1822】[JSOI2010]Frozen Nova 冷凍波 計算幾何+二分+網路流最大流

來源:互聯網
上載者:User

標籤:color   div   攻擊   for   data   val   資料   計算   sample   

題目描述

WJJ喜歡“魔獸爭霸”這個遊戲。在遊戲中,巫妖是一種強大的英雄,它的技能Frozen Nova每次可以殺死一個小精靈。我們認為,巫妖和小精靈都可以看成是平面上的點。 當巫妖和小精靈之間的直線距離不超過R,且巫妖看到小精靈的視線沒有被樹木阻擋(也就是說,巫妖和小精靈的連線與任何樹木都沒有公用點)的話,巫妖就可以瞬間殺滅一個小精靈。 在森林裡有N個巫妖,每個巫妖釋放Frozen Nova之後,都需要等待一段時間,才能再次施放。不同的巫妖有不同的等待時間和施法範圍,但相同的是,每次施放都可以殺死一個小精靈。 現在巫妖的頭目想知道,若從0時刻開始計算,至少需要花費多少時間,可以殺死所有的小精靈?

輸入

輸入檔案第一行包含三個整數N、M、K(N,M,K<=200),分別代表巫妖的數量、小精靈的數量和樹木的數量。 接下來N行,每行包含四個整數x, y, r, t,分別代表了每個巫妖的座標、攻擊範圍和施法間隔(單位為秒)。 再接下來M行,每行兩個整數x, y,分別代表了每個小精靈的座標。 再接下來K行,每行三個整數x, y, r,分別代表了每個樹木的座標。 輸入資料中所有座標範圍絕對值不超過10000,半徑和施法間隔不超過20000。

輸出

輸出一行,為消滅所有小精靈的最短時間(以秒計算)。如果永遠無法消滅所有的小精靈,則輸出-1。

範例輸入

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

範例輸出

5

題解

計算幾何+二分+網路流最大流

首先要解決的是是否能夠攻擊到,如果兩個點形成的線段與所有圓都沒有公用點,那麼就可以攻擊到。

線段與圓有公用點,需要滿足兩個條件之一:(1)線段某端點在圓內 (2)直線與圓有公用點,且以線段和端點與圓心連線的夾角是銳角。

其中直線與圓有公用點可以使用點到直線距離公式:$\frac{|ax_0+by_0+c|}{\sqrt{a^2+b^2}}$,夾角是銳角可以使用餘弦定理的推論:如果$a^2<b^2+c^2$,那麼$A$是銳角。

判斷完以後就是經典的二分+最大流判斷問題了:二分時間,S向巫妖連邊,容量為mid時間攻擊次數;巫妖向能夠攻擊到的小精靈連邊,容量為1;小精靈向T連邊,容量為1。如果滿流則mid可行,否則不可行。

注意攻擊次數的計算公式:$\lfloor\frac{mid}t\rfloor+1$,即開場是沒有冷卻的。(為這個問題糾結了半天= =)

#include <queue>#include <cstdio>#include <cstring>#define N 410#define M 200010using namespace std;typedef long long ll;queue<int> q;ll xn[N] , yn[N] , rn[N] , tn[N] , xm[N] , ym[N] , xk[N] , yk[N] , rk[N];int n , m , k , v[N][N] , head[N] , to[M] , val[M] , next[M] , cnt , s , t , dis[N];inline ll squ(ll x){return x * x;}bool connect(int a , int b){if(squ(xn[a] - xm[b]) + squ(yn[a] - ym[b]) > squ(rn[a])) return 0;int i;for(i = 1 ; i <= k ; i ++ )if(squ(xn[a] - xk[i]) + squ(yn[a] - yk[i]) <= squ(rk[i]) || squ(xm[b] - xk[i]) + squ(ym[b] - yk[i]) <= squ(rk[i]) || (   squ(yn[a] * (xk[i] - xm[b]) - ym[b] * (xk[i] - xn[a]) - yk[i] * (xn[a] - xm[b])) <= squ(rk[i]) * (squ(xn[a] - xm[b]) + squ(yn[a] - ym[b])) &&    squ(xn[a] - xm[b]) + squ(yn[a] - ym[b]) + squ(xn[a] - xk[i]) + squ(yn[a] - yk[i]) >= squ(xm[b] - xk[i]) + squ(ym[b] - yk[i]) &&    squ(xn[a] - xm[b]) + squ(yn[a] - ym[b]) + squ(xm[b] - xk[i]) + squ(ym[b] - yk[i]) >= squ(xn[a] - xk[i]) + squ(yn[a] - yk[i])))return 0;return 1;}void add(int x , int y , int z){to[++cnt] = y , val[cnt] = z , next[cnt] = head[x] , head[x] = cnt;to[++cnt] = x , val[cnt] = 0 , next[cnt] = head[y] , head[y] = cnt;}bool bfs(){int x , i;memset(dis , 0 , sizeof(dis));while(!q.empty()) q.pop();dis[s] = 1 , q.push(s);while(!q.empty()){x = q.front() , q.pop();for(i = head[x] ; i ; i = next[i]){if(val[i] && !dis[to[i]]){dis[to[i]] = dis[x] + 1;if(to[i] == t) return 1;q.push(to[i]);}}}return 0;}int dinic(int x , int low){if(x == t) return low;int temp = low , i , k;for(i = head[x] ; i ; i = next[i]){if(val[i] && dis[to[i]] == dis[x] + 1){k = dinic(to[i] , min(temp , val[i]));if(!k) dis[to[i]] = 0;val[i] -= k , val[i ^ 1] += k;if(!(temp -= k)) break;}}return low - temp;}bool judge(int mid){int i , j , sum = 0;memset(head , 0 , sizeof(head)) , cnt = 1;for(i = 1 ; i <= n ; i ++ ) add(s , i , mid / tn[i] + 1);for(i = 1 ; i <= m ; i ++ ) add(i + n , t , 1);for(i = 1 ; i <= n ; i ++ )for(j = 1 ; j <= m ; j ++ )if(v[i][j])add(i , j + n , 1);while(bfs()) sum += dinic(s , 1 << 30);return sum == m;}int main(){int i , j , l = 0 , r = 2000000 , mid , ans = -1;scanf("%d%d%d" , &n , &m , &k) , s = 0 , t = n + m + 1;for(i = 1 ; i <= n ; i ++ ) scanf("%lld%lld%lld%lld" , &xn[i] , &yn[i] , &rn[i] , &tn[i]);for(i = 1 ; i <= m ; i ++ ) scanf("%lld%lld" , &xm[i] , &ym[i]);for(i = 1 ; i <= k ; i ++ ) scanf("%lld%lld%lld" , &xk[i] , &yk[i] , &rk[i]);for(i = 1 ; i <= n ; i ++ )for(j = 1 ; j <= m ; j ++ )v[i][j] = connect(i , j);while(l <= r){mid = (l + r) >> 1;if(judge(mid)) ans = mid , r = mid - 1;else l = mid + 1;}printf("%d\n" , ans);return 0;}

 

 

 

【bzoj1822】[JSOI2010]Frozen Nova 冷凍波 計算幾何+二分+網路流最大流

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.