zoukankan      html  css  js  c++  java
  • 解题:SCOI 2014 方伯伯运椰子

    题面

    很有趣的一道题,看起来是个神奇网络流,其实我们只要知道网络的一些性质就可以做这道题了

    因为题目要求流量守恒,所以我们其实是在网络中搬运流量,最终使得总费用减小,具体来说我们可以直接把这种“搬运”的关系建出来:

    对于一条从$u$到$v$的边,从$u$向$v$连一条$b+d$的边,如果其上限不为零,再从$v$向$u$连一条$a-d$的边

    那么得到的这张新图其实是描述了图中的费用流,一个合法的搬运方案就是一个环(转了一圈保证流量还是守恒的),然后有一个叫做消圈定理的东西:

    消圈定理:残量网络里如果存在负费用环,那么当前流不是最小费用流。因为通过增加残量网络负权边的流量,减少正权边的流量,一定能得到另一个更优的可行流。

    于是就判负环吧=。=

     1 #include<queue> 
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 const int N=5005,M=3005;
     7 const double eps=1e-4,inf=1e12;
     8 int n,m,t1,t2,t3,cnt,last,from;
     9 double val[2*M+N],dis[N],d1,d2,d3,l,r; 
    10 int p[N],noww[2*M+N],goal[2*M+N],inq[N],vis[N];
    11 queue<int> qs;
    12 void link(int f,int t,double v)
    13 {
    14     noww[++cnt]=p[f],p[f]=cnt;
    15     goal[cnt]=t,val[cnt]=v;
    16 }
    17 bool check(double x)
    18 {
    19     memset(vis,0,sizeof vis);
    20     for(int i=1;i<=n;i++) dis[i]=inf;
    21     dis[from]=0,inq[from]=true,qs.push(from);
    22     while(!qs.empty())
    23     {
    24         int tn=qs.front(); 
    25         inq[tn]=false,qs.pop();
    26         for(int i=p[tn];i;i=noww[i])
    27             if(dis[goal[i]]>dis[tn]+val[i]+x)
    28             {
    29                 dis[goal[i]]=dis[tn]+val[i]+x;
    30                 if(!inq[goal[i]])
    31                 {
    32                     inq[goal[i]]=true,qs.push(goal[i]);
    33                     if(++vis[goal[i]]>n) return false;
    34                 }
    35             }
    36     }
    37     return true;
    38 }
    39 int main()
    40 {
    41     scanf("%d%d",&n,&m),n+=2,r=1500;
    42     for(int i=1;i<=m;i++)
    43     {
    44         scanf("%d%d%lf%lf%d%lf",&t1,&t2,&d1,&d2,&t3,&d3);
    45         if(t1==n-1) {from=t2; continue;}
    46         if(t2==n-1) {from=t1; continue;}
    47         link(t1,t2,d2+d3); if(t3) link(t2,t1,d1-d3); 
    48     }
    49     while(r-l>eps)
    50     {
    51         double mid=(l+r)/2;
    52         if(check(mid)) r=mid;
    53         else l=mid;
    54     }
    55     printf("%.2lf",r);
    56     return 0;
    57 }
    View Code
  • 相关阅读:
    求求你规范下你的代码风格
    为啥用ip不可以访问知乎,而百度却可以?
    漫画:htts是如何保证一台主机把数据安全发给另一台主机
    如何从亿量级中判断一个数是否存在?
    广播路由算法 :我是如何优雅着把悄悄话带给其他人的
    什么?你不知道0.0.0.0和255.255.255.255这两个地址是干嘛的?
    一篇文章带你学会Linux三剑客之一:awk
    你真的了解 i++, ++i 和 i+++++i 以及 i+++i++ 吗?
    通俗易懂讲解TCP流量控制机制,了解一下
    一文读懂拥塞控制
  • 原文地址:https://www.cnblogs.com/ydnhaha/p/9841452.html
Copyright © 2011-2022 走看看