BZOJ3993: [SDOI2015]星際戰爭
阿新 • • 發佈:2018-03-04
log Go find math 接下來 href 網絡 LG tex
3 10
4 6
0 1
1 1
1.300000
戰鬥開始後的前0.5秒,激光武器1攻擊2號巨型機器人,激光武器2攻擊1號巨型機器人。1號巨型機器人被完全摧毀,2號巨型機器人還剩余8的裝甲值;
接下來的0.8秒,激光武器1、2同時攻擊2號巨型機器人。2號巨型機器人被完全摧毀。
對於全部的數據,1<=N, M<=50,1<=Ai<=105,1<=Bi<=1000,輸入數據保證X軍團一定能摧毀Y軍團的所有巨型機器人
Description
3333年,在銀河系的某星球上,X軍團和Y軍團正在激烈地作戰。在戰鬥的某一階段,Y軍團一共派遣了N個巨型機器人進攻X軍團的陣地,其中第i個巨型機器人的裝甲值為Ai。當一個巨型機器人的裝甲值減少到0或者以下時,這個巨型機器人就被摧毀了。X軍團有M個激光武器,其中第i個激光武器每秒可以削減一個巨型機器人Bi的裝甲值。激光武器的攻擊是連續的。這種激光武器非常奇怪,一個激光武器只能攻擊一些特定的敵人。Y軍團看到自己的巨型機器人被X軍團一個一個消滅,他們急需下達更多的指令。為了這個目標,Y軍團需要知道X軍團最少需要用多長時間才能將Y軍團的所有巨型機器人摧毀。但是他們不會計算這個問題,因此向你求助。
Input
第一行,兩個整數,N、M。
第二行,N個整數,A1、A2…AN。 第三行,M個整數,B1、B2…BM。 接下來的M行,每行N個整數,這些整數均為0或者1。這部分中的第i行的第j個整數為0表示第i個激光武器不可以攻擊第j個巨型機器人,為1表示第i個激光武器可以攻擊第j個巨型機器人。Output
一行,一個實數,表示X軍團要摧毀Y軍團的所有巨型機器人最少需要的時間。輸出結果與標準答案的絕對誤差不超過10-3即視為正確。
Sample Input
2 23 10
4 6
0 1
1 1
Sample Output
HINT
【樣例說明1】
戰鬥開始後的前0.5秒,激光武器1攻擊2號巨型機器人,激光武器2攻擊1號巨型機器人。1號巨型機器人被完全摧毀,2號巨型機器人還剩余8的裝甲值;
接下來的0.8秒,激光武器1、2同時攻擊2號巨型機器人。2號巨型機器人被完全摧毀。
對於全部的數據,1<=N, M<=50,1<=Ai<=105,1<=Bi<=1000,輸入數據保證X軍團一定能摧毀Y軍團的所有巨型機器人
題目傳送門
一眼二分+最大流
莫非網絡流代碼抄多了自帶升級效果???
ST---->i 能夠造成的傷害
i---->j 能打的機器人,INF
j----> ed 護甲值
然後枚舉時間就OK了
喪心病狂這道題竟然卡我精度
代碼如下:
#include<cmath> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #define eps 1e-7 using namespace std; double INF=(1<<29); struct dicnic{ int x,y,next,other; double c; }a[2100000];int len,last[210000]; void ins(int x,int y,double c) { int k1,k2; k1=++len; a[len].x=x;a[len].y=y;a[len].c=c; a[len].next=last[x];last[x]=len; k2=++len; a[len].x=y;a[len].y=x;a[len].c=0; a[len].next=last[y];last[y]=len; a[k1].other=k2; a[k2].other=k1; } int st,ed,head,tail; int h[210000],list[210000]; bool bt_h() { memset(h,0,sizeof(h));h[st]=1; list[1]=st;head=1;tail=2; while(head!=tail) { int x=list[head]; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(h[y]==0&&a[k].c>0) { h[y]=h[x]+1; list[tail++]=y; } } head++; } if(h[ed]>0)return true; return false; } double findflow(int x,double f) { if(x==ed)return f; double s=0,t; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(h[y]==h[x]+1&&a[k].c>0&&s<f) { s+=(t=findflow(y,min(a[k].c,f-s))); a[k].c-=t;a[a[k].other].c+=t; } } if(s==0)h[x]=0; return s; } int n,m; double b[51]; double c[51]; int f[51][51]; bool check(double x) { double sum=0.0; len=0;memset(last,0,sizeof(last)); for(int i=1;i<=m;i++)ins(st,i,x*c[i]); for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) if(f[i][j]==1) ins(i,j+m,INF); for(int i=1;i<=n;i++)ins(i+m,ed,b[i]),sum+=b[i]; double ans=0.0; while(bt_h()==true)ans+=findflow(st,INF); if(abs(ans-sum)<=eps)return true; return false; } int main() { scanf("%d%d",&n,&m);st=0,ed=n+m+1; len=0;memset(last,0,sizeof(last)); for(int i=1;i<=n;i++)scanf("%lf",&b[i]); for(int i=1;i<=m;i++)scanf("%lf",&c[i]); for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) scanf("%d",&f[i][j]); double l=0.0,r=10000000.0;double ans; while(l<=r) { double mid=(l+r)/2; if(check(mid)==true){r=mid-eps;ans=mid;} else l=mid+eps; } printf("%.6lf\n",ans); return 0; }
by_lmy
BZOJ3993: [SDOI2015]星際戰爭