Luo Gu P3324 [SDOI2015] War of the Worlds

Title: Luo Gu P3324 [SDOI2015] War of the Worlds

Ideas:

Similar to the "missile towers", because the topics to ensure a solution, it takes a certain time can not destroy all the enemies is less than the final answer, as long as it takes longer than equal to the final answer can destroy all the enemies, the answer is monotone, consider half the answer.
After half an answer, converted to determine the problem. When the total time is fixed, the total amount of damage each weapon is determined.
Can then be modeled by a network flow: enemy weapons and divided into two parts, from source s connected to the side arms, the capacity of the total amount of damage that can be output arms (currently assigned to two time the weapon time * dps); per weapons to the enemy to attack it may even edge, capacity inf; each enemy to the Meeting point t even side, the upper limit of capacity for the life of the enemy. Just last enemy to determine the maximum flow is equal to the total value of life.
Because time is a fraction, using the code stored in double. Finally requires three decimal places, you can put all the data becomes integer multiplied by 10,000 to improve accuracy.
Note that the code I n, m, a, b opposite to the title.


Code:

#include <bits/stdc++.h>
using namespace std;
const int N=5e5+5,inf=0x3f3f3f3f;
const double eps=1e-4;
double sum,a[N],b[N],val[N];
int n,m,s,t,tot,mp[505][505],d[N];
int Top=1,ver[N],nxt[N],head[N];
inline void add(int u,int v,double w){
    ver[++Top]=v;val[Top]=w;nxt[Top]=head[u];head[u]=Top;
    ver[++Top]=u;val[Top]=0;nxt[Top]=head[v];head[v]=Top;
}
bool bfs(){
    for(int i=1;i<=tot;++i) d[i]=0;
    queue<int> q;
    q.push(s);
    d[s]=1;
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=head[u];i;i=nxt[i]){
            int v=ver[i];
            if(val[i]>eps&&!d[v]){
                d[v]=d[u]+1;
                if(v==t) return true;
                q.push(v);
            }
        }
    }
    return false;
}
double dfs(int u,double flow){
    if(u==t) return flow;
    double left=flow;
    for(int i=head[u];i&&left;i=nxt[i]){
        int v=ver[i];
        if(val[i]>eps&&d[v]==d[u]+1){
            double res=dfs(v,min(left,val[i]));
            if(!res) d[v]=0;
            val[i]-=res;
            val[i^1]+=res;
            left-=res;
        }
    }
    return flow-left;
}
bool check(double tim){
    memset(head,0,sizeof(head));
    memset(ver,0,sizeof(ver));
    memset(nxt,0,sizeof(nxt));
    memset(val,0,sizeof(val));
    Top=1;
    for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
            if(mp[i][j]) add(i,n+j,inf);
        }
    }
    for(int i=1;i<=n;++i) add(s,i,tim*a[i]);
    for(int i=1;i<=m;++i) add(n+i,t,b[i]);
    double res=0;
    while(bfs()) {
        res+=dfs(s,inf);
    }
    return fabs(res-sum)<eps;
}
int main(){
    scanf("%d%d",&m,&n);
    for(int i=1;i<=m;++i) scanf("%lf",&b[i]);
    for(int i=1;i<=n;++i) scanf("%lf",&a[i]);
    for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
            scanf("%d",&mp[i][j]);
        }
    }
    tot=n+m;
    s=++tot;
    t=++tot;
    for(int i=1;i<=m;++i) sum+=b[i];
    double l=0,r=2e5;
    while(r-l>eps){
        double mid=(l+r)*0.5;
        if(check(mid)) r=mid;
        else l=mid;
    }
    printf("%.3lf",l);
    return 0;
}

Guess you like

Origin www.cnblogs.com/yu-xing/p/11322417.html