今天做了SDOI Day2 觉得自己萌萌哒= =题目真的有点水,一点编程复杂度都没有
T1:星际战争
描述:http://www.lydsy.com/JudgeOnline/problem.php?id=3993
这道题是这两天最容易的题了吧。。
可以发现这是一个二分图,考虑二分答案,那么人们在这段时间的输出伤害就能够确定了,用最大流判断是否所有的机器人护甲值都为0,即可。
数据较良心跑得飞快
Code:
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 #define maxn 105 7 #define maxm 3000 8 struct edges{ 9 int to,next;double cap; 10 }edge[maxm*2]; 11 int l,next[maxn]; 12 inline void addedge(int x,int y,double z) { 13 l++; 14 edge[l*2]=(edges){y,next[x],z};next[x]=l*2; 15 edge[l*2+1]=(edges){x,next[y],0};next[y]=l*2+1; 16 } 17 int p[maxn],gap[maxn],h[maxn],s,t; 18 double sap(int u,double flow) { 19 if (u==t) return flow; 20 double cnt=0; 21 for (int i=p[u];i;i=edge[i].next) 22 if (edge[i].cap&&h[edge[i].to]+1==h[u]) { 23 double cur=sap(edge[i].to,min(flow-cnt,edge[i].cap)) ; 24 edge[i].cap-=cur;edge[i^1].cap+=cur; 25 p[u]=i; 26 if ((cnt+=cur)==flow) return flow; 27 } 28 if (!(--gap[h[u]])) h[s]=t; 29 gap[++h[u]]++; 30 p[u]=next[u]; 31 return cnt; 32 } 33 inline double maxflow(){ 34 for (int i=1;i<=t;i++) p[i]=next[i]; 35 memset(h,0,sizeof(h)); 36 memset(gap,0,sizeof(gap)); 37 gap[0]=t; 38 double flow=0; 39 while (h[s]<t) flow+=sap(s,1e7); 40 return flow; 41 } 42 int a[maxn],b[maxn]; 43 bool c[maxn][maxn]; 44 int n,m; 45 inline void build(double mid){ 46 l=0; 47 s=n+m+1,t=n+m+2; 48 memset(next,0,sizeof(next)); 49 for (int i=1;i<=n;i++) addedge(s,i,mid*a[i]); 50 for (int i=1;i<=m;i++) addedge(i+n,t,b[i]); 51 for (int i=1;i<=n;i++) 52 for (int j=1;j<=m;j++) 53 if (c[i][j]) addedge(i,j+n,5e6); 54 } 55 int main(){ 56 scanf("%d%d",&m,&n); 57 int sum=0; 58 for (int j=1;j<=m;j++) { 59 scanf("%d",b+j);sum+=b[j]; 60 } 61 for (int i=1;i<=n;i++) scanf("%d",a+i); 62 for (int i=1;i<=n;i++) 63 for (int j=1;j<=m;j++) scanf("%d",c[i]+j); 64 double l=0,r=5e6; 65 while (r-l>1e-4) { 66 double mid=(l+r)/2; 67 build(mid); 68 if (maxflow()<sum) l=mid; 69 else r=mid; 70 } 71 printf("%lf\n",r); 72 return 0; 73 }