zoukankan      html  css  js  c++  java
  • BZOJ2285 : [Sdoi2011]保密

    首先通过分数规划,二分答案$mid$,将每条边边权重置为$t-mid imes s$,用DP求出终点到该点的最短路,若非正则可以更小。

    如此可以计算出每个出入口的最小危险值,然后把奇点放在$S$,偶点放在$T$,代价为危险值,对于每个空腔,在相应点之间连无穷边,求最小割即可。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=705,M=100010;
    const double inf=1e9,eps=3e-4;
    int n,m,n1,m1,i,x,y,d[N],g[N],v[M],wt[M],ws[M],nxt[M],ed,h,t,q[N],vis[N];double f[N];
    inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
    inline void add(int x,int y){d[y]++;v[++ed]=y;read(wt[ed]);read(ws[ed]);nxt[ed]=g[x];g[x]=ed;}
    void dfs(int x){
      if(vis[x])return;
      vis[x]=1;
      for(int i=g[x];i;i=nxt[i])dfs(v[i]);
    }
    inline bool check(int T,double p){
      int i,x,j;
      for(i=1;i<n;i++)f[i]=inf;
      for(i=1;i<=n;i++){
        x=q[i];
        if(x==T)return f[x]<eps;
        for(j=g[x];j;j=nxt[j])f[v[j]]=min(f[v[j]],f[x]+wt[j]-p*ws[j]);
      }
    }
    inline double cal(int x){
      if(!vis[x])return inf;
      double l=0.1,r=10,mid;
      while(l+eps<r)if(check(x,mid=(l+r)/2))r=mid;else l=mid;
      return(l+r)/2;
    }
    namespace Flow{
    struct E{int t;double f;E*nxt,*pair;}*g[N],*d[N],pool[90000],*cur=pool;
    int S,T,h[N],gap[N];double ans;
    inline void add(int s,int t,double f){
      E*p=cur++;p->t=t;p->f=f;p->nxt=g[s];g[s]=p;
      p=cur++;p->t=s;p->f=0;p->nxt=g[t];g[t]=p;
      g[s]->pair=g[t];g[t]->pair=g[s];
    }
    double sap(int v,double flow){
      if(v==T)return flow;
      double rec=0;
      for(E*p=d[v];p;p=p->nxt)if(h[v]==h[p->t]+1&&p->f>eps){
        double ret=sap(p->t,min(flow-rec,p->f));
        p->f-=ret;p->pair->f+=ret;d[v]=p;
        rec+=ret;
        if(rec+eps>flow)return flow;
      }
      if(!(--gap[h[v]]))h[S]=T;
      gap[++h[v]]++;d[v]=g[v];
      return rec;
    }
    void solve(){
      for(gap[0]=T,i=1;i<=T;i++)d[i]=g[i];
      while(h[S]<T)ans+=sap(S,inf);
      if(ans>1e8)puts("-1");else printf("%.1f",ans);
    }
    }
    int main(){
      read(n),read(m);
      for(i=1;i<=m;i++)read(x),read(y),add(x,y);
      dfs(n);
      for(h=i=1;i<=n;i++)if(!d[i])q[++t]=i;
      while(h<=t)for(i=g[x=q[h++]];i;i=nxt[i])if(!(--d[v[i]]))q[++t]=v[i];
      read(m1),read(n1);
      Flow::S=n1+1;
      Flow::T=n1+2;
      for(i=1;i<=n1;i++)if(i&1)Flow::add(n1+1,i,cal(i));else Flow::add(i,n1+2,cal(i));
      while(m1--)read(x),read(y),Flow::add(x,y,inf);
      Flow::solve();
      return 0;
    }
    

      

  • 相关阅读:
    Berkeley DB(五) 补充
    案例研究–亚马逊服务中断,数据库崩溃–我们恢复数据库且无数据损失
    源代码管理十诫
    menucool
    如何:使用變數視窗將變數加入封裝
    翻转句子中单词的顺序
    【科研论文】新型脉冲电子围栏网络化系统设计
    Java对泛型的支持(二)
    springmvc camel mybatis集成实例及分析
    xtrabackup全备方案,备份恢复全过程记录
  • 原文地址:https://www.cnblogs.com/clrs97/p/5792052.html
Copyright © 2011-2022 走看看