zoukankan      html  css  js  c++  java
  • P3324 [SDOI2015]星际战争 二分 + 网络流

      

    为 二分加网络流  二分答案即可

    图很好建  注意double型二分的写法。。一开始  1 加  fabs    2 L+一个值  R-一遍

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define ll long long
    #define pb push_back
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 0x3f3f3f3f
    const int N=1e4+44;
    const int M=1e4+54;
    double eps=1e-4;
    int d[N];
    struct edge {
        int to, next;double w;
    } e[M << 1];
    int head[N],cur[N],cnt = 1;
    void add(int x, int y, double z) {
        e[++cnt] = (edge){y, head[x], z};
        head[x] = cnt;
        e[++cnt] = (edge){x, head[y], 0};
        head[y] = cnt;
    }
    void init()
    {   
        rep(i,0,cnt)head[i]=0;
        cnt=1;
    }
    int level[N];
    bool bfs(int s, int t) {
        memset(level, 0, sizeof level);
        queue<int> q;
        level[s] = 1;
        q.push(s);
        while (!q.empty()) {
            int pos = q.front();q.pop();
            for (int i = head[pos]; i; i = e[i].next) {
                int nx = e[i].to;
                if (!e[i].w || level[nx]) continue;
                level[nx] = level[pos] + 1;
                q.push(nx);
            }
        }
        return level[t];
    }
    double dfs(int s, int t, double flow) {
        if(s==t||flow==0)return flow;
        double f,ret = 0;
        for (int &i = cur[s],v; i; i = e[i].next) {
             v = e[i].to;
            if (level[v] == level[s] + 1 && (f=dfs(v,t,min(flow,e[i].w)))>0) {
                e[i].w -= f;
                e[i ^ 1].w += f;
                flow -= f;
                ret += f;
                if(!flow)break;
            }
        }
        return ret;
    }
    double dinic(int s, int t) {
        double ret = 0.0;
        while (bfs(s, t)) memcpy(cur,head,sizeof cur),ret += dfs(s, t, inf);
        return ret;
    }
    int n,m,s,t,a,b,c,S,T;
    int hp[N],attack[N],sum,mp[100][100];
    
    bool check(double  mid)
    {   
        init();
        rep(i,1,n)add(i,t,1.0*hp[i]);
        rep(i,1,m)
        {
            add(s,i+n,1.0*mid*attack[i]);
            rep(j,1,n)
            {   
                if(mp[i][j])
                add(i+n,j,1.0*inf);
            }
        }
        double ans=dinic(s,t);
        return fabs(ans-1.0*sum)<=eps;
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);s=n+m+1,t=s+1;
        rep(i,1,n)scanf("%d",&hp[i]),sum+=hp[i];
        rep(i,1,m)scanf("%d",&attack[i]);
        rep(i,1,m)rep(j,1,n)scanf("%d",&mp[i][j]);
        double L=0,R=1000000,ans=0;
        while(R-L>=0.001)
        {   
            double mid=(L+R)/2;
            if(check(mid))R=mid,ans=mid;
            else L=mid; 
        }
        printf("%.6f",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    poj1019
    poj1017
    .net面试题及答案二
    .net面试题集锦一
    .net面试题目三
    ADO.NET中的五个主要对象
    ASP.NET页面生命周期描述(转)
    学习网址不断更新。。。
    Html5新标签解释及用法
    HTML5 Shiv – 让该死的IE系列支持HTML5吧
  • 原文地址:https://www.cnblogs.com/bxd123/p/11493056.html
Copyright © 2011-2022 走看看