• SDOI2013 费用流


    题目链接:戳我

    emmmm就是在可行的最大流里面让最大边最小。我们可以进行二分+限流然后跑dinic,看是否能跑满即可。

    代码如下:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #define eps 1e-6
    #define S 1
    #define T n
    #define MAXN 100010
    #define INF 1e9
    using namespace std;
    int n,m,t=1,p;
    int head[MAXN<<1],dep[MAXN],cur[MAXN<<1];
    double maxx;
    struct Edge{int nxt,to;double dis;}edge[MAXN<<1],pre[MAXN<<1];
    inline void add(int from,int to,double dis)
    {
      edge[++t].nxt=head[from],edge[t].to=to,edge[t].dis=dis,head[from]=t;
      edge[++t].nxt=head[to],edge[t].to=from,edge[t].dis=0,head[to]=t;
    }
    inline bool bfs()
    {
      queue<int>q;
      memset(dep,0x3f,sizeof(dep));
      memcpy(cur,head,sizeof(head));
      q.push(S);dep[S]=0;
      while(!q.empty())
      {
        int u=q.front();q.pop();
        //printf("u=%d
    ",u);
        for(int i=head[u];i;i=edge[i].nxt)
        {
          int v=edge[i].to;
          //printf("v=%d dep[v]=%d dis=%.2lf
    ",v,dep[v],edge[i].dis);
          if(dep[v]==0x3f3f3f3f&&edge[i].dis>eps)
            dep[v]=dep[u]+1,q.push(v);
        }
        //puts("");
      }
      if(dep[T]==0x3f3f3f3f) return false;
      return true;
    }
    inline double dfs(int x,double f)
    {
      if(f<eps||x==T) return f;
      double w,used=0;
      for(int i=cur[x];i;i=edge[i].nxt)
      {
        int v=edge[i].to;
        cur[x]=i;
        if(dep[v]==dep[x]+1&&(w=dfs(v,min(edge[i].dis,f))))
        {
          edge[i].dis-=w,edge[i^1].dis+=w;
          f-=w,used+=w;
          if(f<eps) break;
        }
      }
      return used;
    }
    inline double dinic()
    {
      double cur_ans=0;
      while(bfs()) cur_ans+=dfs(S,INF);
      return cur_ans;
    }
    inline bool check(double limit)
    {
      //cout<<"limit="<<limit<<endl;
      for(int i=2;i<=t;i++) edge[i].dis=min(pre[i].dis,limit);
      //for(int i=2;i<=t;i++) cout<<edge[i].dis<<" ";
      double cur_ans=dinic();
      //cout<<endl<<"cur_ans="<<cur_ans<<endl;
      if(maxx-cur_ans<eps) return true;
      return false;
    }
    int main()
    {
      #ifndef ONLINE_JUDGE
      freopen("ce.in","r",stdin);
      #endif
      scanf("%d%d%d",&n,&m,&p);
      for(int i=1;i<=m;i++)
      {
        int u,v,w;
        scanf("%d%d%d",&u,&v,&w);
        add(u,v,w);
      }
      for(int i=2;i<=t;i++) pre[i].dis=edge[i].dis;
      maxx=dinic();
      double l=0,r=50000.0;
      //cout<<"maxx="<<maxx<<endl;
      while(r-l>eps)
      {
        double mid=(l+r)/2;
        if(check(mid)) r=mid;
        else l=mid;
      }
      printf("%d
    ",(int)maxx);
      printf("%.4lf
    ",l*(p*1.0));
      return 0;
    }
    
    
  • 相关阅读:
    校园WebGIS开发与实践(论文部分)
    初来博客园,请多多关照
    MIFtoTAB and TABtoMIF(MIF和TAB互转小工具)
    MIFtoSHP通用转换工具
    activity 对home 按钮事件的处理
    在XML布局文件里,会遇到的一些单位
    自己写的Adapter 无法被鼠标点中问题
    linux 下查看文件修改时间 等
    Android中使用GridView分页显示系统所安装的应用,支持拖动与手势滑动
    getLaunchIntentForPackage 获取到的为null原因
  • 原文地址:https://www.cnblogs.com/fengxunling/p/10367925.html
Copyright © 2020-2023  润新知