今天做了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 }
View Code

相关文章: