zoukankan      html  css  js  c++  java
  • (最优比例环)POJ 3621

    题意:

    在一个有向加权图中找到一个环,使这个环点权和/边权和 最大

    分析:

    一开始还没做过最优比率生成树,但是看到过,两题都A不了。

    后来看了题解,索性一起撸掉。

    这题可以用类似最优比率生成树的方法做,二分答案。

    具体: 这个题解讲的很详细了。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <vector>
     5 #include <queue>
     6 
     7 
     8 using namespace std;
     9 
    10 const int inf=0x3f3f3f3f;
    11 const int maxn=1010;
    12 
    13 #define eps (1e-6)
    14 
    15 int sgn(double x) {
    16     return x<-eps?-1:x>eps?1:0;
    17 }
    18 
    19 int n,m;
    20 
    21 bool vis[maxn];
    22 int cnt[maxn];
    23 int val[maxn];
    24 double dist[maxn];
    25 
    26 struct Edge {
    27     int v;
    28     double cost;
    29     Edge(int _v=0,double _cost=0.0) {
    30         v=_v;
    31         cost=_cost;
    32     }
    33 };
    34 
    35 vector<Edge> edge[maxn];
    36 
    37 
    38 bool SPFA(double rate) {
    39     memset(vis,0,sizeof(vis));
    40     memset(cnt,0,sizeof(cnt));
    41     memset(dist,0,sizeof(dist));
    42     queue<int> q;
    43     while(!q.empty())q.pop();
    44     for(int i=1; i<=n; i++) {
    45         dist[i]=0;
    46         vis[i]=1;
    47         cnt[i]=1;
    48         q.push(i);
    49     }
    50     while(!q.empty()) {
    51         int u = q.front();
    52         q.pop();
    53         vis[u]=false;
    54         for(int i=0; i<edge[u].size(); i++) {
    55             int v= edge[u][i].v;
    56             double w=edge[u][i].cost*rate-val[v];
    57             if(dist[v]>dist[u]+w) {
    58                 dist[v]=dist[u]+w;
    59                 if(!vis[v]) {
    60                     vis[v]=true;
    61                     q.push(v);
    62                     if(++cnt[v]>n)return false;
    63                 }
    64             }
    65         }
    66     }
    67     return true;
    68 }
    69 
    70 
    71 int main() {
    72     while(~scanf("%d%d",&n,&m)) {
    73         for(int i=1; i<=n; i++) {
    74             scanf("%d",&val[i]);
    75             edge[i].clear();
    76         }
    77         for(int i=0; i<m; i++) {
    78             int u,v;
    79             double c;
    80             scanf("%d%d%lf",&u,&v,&c);
    81             edge[u].push_back(Edge(v,c));
    82         }
    83         double left=0;
    84         double right=1000;
    85         while(sgn(left-right)<0) {
    86             double mid=(left+right)/2;
    87             if(!SPFA(mid)) {
    88                 left=mid;
    89             } else {
    90                 right=mid;
    91             }
    92         }
    93         printf("%.2f
    ",left);
    94     }
    95     return 0;
    96 
    97 }
  • 相关阅读:
    《XXX重大技术需求征集系统》的可用性和可修改性战术分析
    淘宝网的软件质量属性分析
    软件架构师如何工作
    PHP 运算符
    PHP函数
    PHP自定义函数
    Mysql 允许外连
    PHP 小练习题持续更新
    文本文件编辑命令
    工作目录切换命令、打包压缩文件命令
  • 原文地址:https://www.cnblogs.com/tak-fate/p/6789672.html
Copyright © 2011-2022 走看看