• 【poj3621】最优比率环


    题意:

    给定n个点,每个点有一个开心度F[i],每个点有m条单向边,每条边有一个长度d,要求一个环,使得它的 开心度的和/长度和 这个比值最大。
    n<=1000,m<=5000

     

    题解:

    最优比率环,很像以前做过的一题最优比率生成树。
    首先二分一个答案r=sigma(xi*fi)/sigma(xi*di),设z=r*sigma(xi*di)-sigma(xi*fi),若能找到一个环满足z<=0,则代表sigma(xi*fi)>=r*sigma(xi*di),则r可以比当前的r要大,则l=mid;否则r=mid;
    判断能否有一个环满足让z<=0,我们就让所有的边权=r*di-f[a[i].x],然后用spfa判负环即可。

     

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<queue>
     7 #include<vector>
     8 #include<cmath>
     9 using namespace std;
    10 
    11 const int N=1100,M=5100;
    12 const double INF=(double)1e9;
    13 int n,m,len,first[N],cnt[N];
    14 double dis[N],F[N];
    15 bool in[N];
    16 struct node{
    17     int x,y,next;
    18     double d,w;
    19 }a[2*M];
    20 queue<int> q;
    21 
    22 double mid;
    23 
    24 double myabs(double x){return x>0 ? x:-x;}
    25 
    26 void ins(int x,int y,double d)
    27 {
    28     a[++len].x=x;a[len].y=y;a[len].d=d;
    29     a[len].next=first[x];first[x]=len;
    30 }
    31 
    32 double spfa(int st)
    33 {
    34     while(!q.empty()) q.pop();
    35     for(int i=1;i<=n;i++) dis[i]=INF;
    36     memset(cnt,0,sizeof(cnt));
    37     memset(in,0,sizeof(in));
    38     q.push(st);dis[st]=0;in[st]=1;
    39     while(!q.empty())
    40     {
    41         int x=q.front();in[x]=0;cnt[x]++;q.pop();
    42         if(cnt[x]==n) return 1;
    43         for(int i=first[x];i;i=a[i].next)
    44         {
    45             int y=a[i].y;
    46             if(dis[y]>=dis[x]+a[i].w)
    47             {
    48                 dis[y]=dis[x]+a[i].w;
    49                 if(!in[y]) in[y]=1,q.push(y);
    50             }
    51         }
    52     }
    53     return 0;
    54 }
    55 
    56 bool check(double r)
    57 {
    58     for(int i=1;i<=len;i++) a[i].w=r*a[i].d-F[a[i].x];
    59     return spfa(1);
    60 }
    61 
    62 int main()
    63 {
    64     freopen("a.in","r",stdin);
    65     scanf("%d%d",&n,&m);
    66     len=0;
    67     memset(first,0,sizeof(first));
    68     double l=0,r=0;
    69     for(int i=1;i<=n;i++) 
    70     {
    71         scanf("%lf",&F[i]);
    72         r+=F[i];
    73     }
    74     for(int i=1;i<=m;i++)
    75     {
    76         int x,y;double d;
    77         scanf("%d%d%lf",&x,&y,&d);
    78         ins(x,y,d);
    79     }
    80     while(l<r)
    81     {
    82         mid=(l+r)/2;
    83         if(check(mid)) l=mid;
    84         else r=mid;
    85         if(myabs(l-r)<=0.0000001) break;
    86     }
    87     mid=6.0;
    88     if(myabs(l)<=0.0000001) printf("0
    ");
    89     else printf("%.2lf
    ",l);
    90     return 0;
    91 }

     

  • 相关阅读:
    Android系统API综述
    Android中的WeakReference 弱引用
    Android代码编译环境配置 “Gerrit和Git环境配置”
    Android源代码下载 “Gerrit下载源代码”
    Android源代码编译过程及指令
    Android的Launcher启动流程 “Launcher部分启动流程”
    Android Frameworks的base目录内容分析 “Android Frameworks base”
    Android系统源代码目录结构 “Android源代码”“目录结构”
    (Android UI)Android应用程序中资源:图片、字符串、颜色、布局等
    (Android UI)Action Bar
  • 原文地址:https://www.cnblogs.com/KonjakJuruo/p/5990304.html
Copyright © 2020-2023  润新知