[BZOJ3993]-[SDOI2015]星际战争-二分答案+最大流
2018-01-20 21:11
393 查看
说在前面
并没有什么想要说的,但是要保持格式题目
BZOJ3993传送门原题面描述很清楚
看题可以戳传送门
解法
可以发现,如果要在最短的时间内灭掉所有机器人,说明需要分配最优方案,使得造成的伤害能尽早达成要求并且,如果在t时间内已经可以消灭所有机器人,那么t+1也一定可以,于是发现答案满足二分性
于是,问题就变成了,在限定的时间内(相当于限定了每个武器的输出),判断能否可行,于是就最大流check了
下面是自带大常数的代码
#include <cstdio> #include <cstring> #include <algorithm> using namespace std ; const double inf = 1e10 , eps = 1e-8 ; int N , M , acce[55][55] , head[105] , tp , S , T ; double atk[55] , def[55] , mid , sum ; struct Path{ int pre , to ; double flow ; }p[2*50*50+4*50+5] ; template <typename T> bool operator !( const T &A ){ if( A < eps && A > -eps ) return true ; return false ; } void In( int t1 , int t2 , double t3 ){ p[++tp] = ( Path ){ head[t1] , t2 , t3 } ; head[t1] = tp ; } void build(){ tp = 1 ; memset( head , 0 , sizeof( head ) ) ; for( int i = 1 ; i <= M ; i ++ ) for( int j = 1 ; j <= N ; j ++ ) if( acce[i][j] ){ In( i , j + M , inf ) ; In( j + M , i , 0 ) ; } for( int i = 1 ; i <= N ; i ++ ){ In( i + M , T , def[i] ) ; In( T , i + M , 0 ) ; } for( int i = 1 ; i <= M ; i ++ ){ In( S , i , mid * atk[i] ) ; In( i , S , 0 ) ; } } int dis[105] , que[105] , fr , ba ; bool BFS(){ memset( dis , -1 , sizeof( dis ) ) ; fr = 1 , ba = 0 ; dis[S] = 0 ; que[++ba] = S ; while( fr <= ba ){ int u = que[fr++] ; for( int i = head[u] ; i ; i = p[i].pre ){ int v = p[i].to ; if( dis[v] != -1 || !p[i].flow ) continue ; dis[v] = dis[u] + 1 ; que[++ba] = v ; } } return dis[T] != -1 ; } double dfs( int u , double flow ){ if( u == T || !flow ) return flow ; double rt = 0 ; for( int i = head[u] ; i ; i = p[i].pre ){ int v = p[i].to ; if( dis[v] != dis[u] + 1 || !p[i].flow ) continue ; double nowf = dfs( v , min( flow , p[i].flow ) ) ; if( !(!nowf) ){ flow -= nowf ; rt += nowf ; p[i].flow -= nowf ; p[i^1].flow += nowf ; if( !flow ) break ; } } if( !rt || !(!flow) ) dis[u] = -1 ; return rt ; } bool check(){ build() ; double tmp = sum ; while( BFS() ) tmp -= dfs( S , inf ) ; return tmp <= 0 ; } void solve(){ double lf = 0 , rg = 50*1e5 , ans ; while( rg - lf >= 5*1e-5 ){ mid = ( rg + lf ) / 2 ; if( check() ){ rg = ans = mid ; } else lf = mid ; } printf( "%f" , ans ) ; } int main(){ scanf( "%d%d" , &N , &M ) ; S = N + M + 1 , T = S + 1 ; for( int i = 1 ; i <= N ; i ++ ) scanf( "%lf" , &def[i] ) , sum += def[i] ; for( int i = 1 ; i <= M ; i ++ ) scanf( "%lf" , &atk[i] ) ; for( int i = 1 ; i <= M ; i ++ ) for( int j = 1 ; j <= N ; j ++ ) scanf( "%d" , &acce[i][j] ) ; solve() ; }
相关文章推荐
- 【二分答案】【最大流】bzoj3993 [Sdoi2015]星际战争
- BZOJ 3993 Sdoi2015 星际战争 二分答案+最大流
- 【BZOJ3993】星际战争(SDOI2015)-二分答案+最大流
- bzoj 3993: [SDOI2015]星际战争 二分答案+最大流
- [BZOJ3993][SDOI2015]星际战争(二分答案+最大流)
- BZOJ 3993 [SDOI2015]星际战争 | 网络流 二分答案
- bzoj 3993: [SDOI2015]星际战争 二分答案&网络流
- 【bzoj3993】[SDOI2015]星际战争 二分+最大流
- BZOJ 3993 [SDOI2015]星际战争 二分+最大流
- [BZOJ3993][SDOI2015]星际战争(二分+最大流)
- BZOJ 3993: [SDOI2015]星际战争 [二分答案 二分图]
- [bzoj3993][SDOI2015]星际战争-二分+最大流
- [SDOI2015][bzoj3993] 星际战争 [二分+最大流]
- bzoj 3993: [SDOI2015]星际战争 (二分+最大流)
- 【bzoj3993】[SDOI2015]星际战争 二分+最大流
- bzoj3993 [SDOI2015]星际战争 二分答案+网络流检验
- 【BZOJ3993】[SDOI2015]星际战争 二分+最大流
- BZOJ_3993_[SDOI2015]星际战争_二分+网络流
- 【BZOJ】3993 [SDOI2015]星际战争 二分+网络流
- 【BZOJ3993】【SDOI2015】星际战争(网络流+二分)