羅区P3324 [SDOI2015]宇宙戦争

タイトル:羅区P3324 [SDOI2015]宇宙戦争

アイデア:

トピックは、ソリューションを確保するため、「ミサイル塔」と同様に、それは一定の時間がかかり、すべての敵を破壊することはできません最終的な答え未満である限り、それが最終的な答えに長い等しい以上かかると、すべての敵を破壊することができ、答えが半分答えを検討し、単調です。
半分答えた後、問題を決定するために変換されます。合計時間が固定されている場合、ダメージの総量各武器が決定されます。
ソースs接続側アームから、敵の武器を2つの部分に分け、(現在、2つの時間武器時間* DPSに譲渡された)出力アームとすることができるダメージの総量の容量;あたり:次いで、ネットワーク・フローによってモデル化することができます。それを攻撃する敵に武器できるさえエッジ、容量INF、ミーティングポイントTにそれぞれ敵さえ側、敵の生活能力の上限。最大流量を決定するだけで、最後の敵は、人生の合計値に等しいです。
時間は、二重に保存されているコードを使用して、分数ですので。最後に小数点以下3桁を必要とし、あなたはすべてのデータが正確さを向上させるために万を乗じた整数になり置くことができます。
タイトルのコードがI、N、M、Bの反対のことに注意してください。


コード:

#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;
}

おすすめ

転載: www.cnblogs.com/yu-xing/p/11322417.html