• BZOJ1486 [HNOI2009]最小圈


    今年的最后一篇了呢。。。好伤感的说,2014年还有1h就过去了

    不不不回到正题,这道题嘛~看上去好神啊!

    看到此题,我们可以联想到最优比例MST,于是就有了方法:

    首先二分答案ans,判断ans是否可行,那如何判断呢?

    每条边边权 - ans,之后在新的图中找负环即可。(可以用dfs版的spfa)

      1 /**************************************************************
      2     Problem: 1486
      3     User: rausen
      4     Language: C++
      5     Result: Accepted
      6     Time:284 ms
      7     Memory:1156 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <cstring>
     12  
     13 using namespace std;
     14 typedef double lf;
     15 const int N = 3005;
     16 const int M = 10005;
     17 const int inf = 1e9;
     18 const lf eps = 1e-10;
     19  
     20 inline int read() {
     21     int x = 0, sgn = 1;
     22     char ch = getchar();
     23     while (ch < '0' || '9' < ch) {
     24         if (ch == '-') sgn = -1;
     25         ch = getchar();
     26     }
     27     while ('0' <= ch && ch <= '9') {
     28         x = x * 10 + ch - '0';
     29         ch = getchar();
     30     }
     31     return sgn * x;
     32 }
     33  
     34 struct Edge {
     35     int x, y;
     36     lf v;
     37      
     38     inline void Read() {
     39         x = read(), y = read();
     40         scanf("%lf", &v);
     41     }
     42 } E[M];
     43  
     44 struct edge {
     45     int next, to;
     46     lf v;
     47     edge() {}
     48     edge(int _n, int _t, lf _v) : next(_n), to(_t), v(_v) {}
     49 } e[M];
     50  
     51 int n, m;
     52 int first[N], tot;
     53 lf d[N];
     54 bool f, v[N];
     55  
     56 inline void add_edge(int x, int y, lf v) {
     57     e[++tot] = edge(first[x], y, v);
     58     first[x] = tot;
     59 }
     60  
     61 void spfa(int p) {
     62     int x, y;
     63     v[p] = 1;
     64     for (x = first[p]; x; x = e[x].next)
     65         if (d[p] + e[x].v < d[y = e[x].to]) {
     66             if (v[y]) {
     67                 f = 1;
     68                 break;
     69             } else
     70                 d[y] = d[p] + e[x].v, spfa(y);
     71         }
     72     v[p] = 0;
     73 }
     74  
     75 void build_graph(lf x) {
     76     int i;
     77     tot = 0, memset(first, 0, sizeof(first));
     78     for (i = 1; i <= m; ++i)
     79         add_edge(E[i].x, E[i].y, E[i].v - x);
     80 }
     81  
     82 bool check(lf x) {
     83     int i;
     84     build_graph(x);
     85     memset(v, 0, sizeof(v)), memset(d, 0, sizeof(d));
     86     for (i = 1, f = 0; i <= n; ++i) {
     87         spfa(i);
     88         if (f) return 1;
     89     }
     90     return 0;
     91 }
     92  
     93 int main() {
     94     int i;
     95     scanf("%d%d", &n, &m);
     96     for (i = 1; i <= m; ++i)
     97         E[i].Read();
     98     lf l = -inf, r = inf, mid;
     99     while (l + eps < r) {
    100         mid = (l + r) / 2;
    101         if (check(mid)) r = mid; else l = mid;
    102     }
    103     printf("%.8lf
    ", l);
    104     return 0;
    105 }
    View Code

    (p.s.  这就是神奇的叫"分数规划"的东西!!!)

    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    .gitignore 文件没起作用
    HTML 中img标签不显示
    关于拖拽
    关于javascript三目
    封装ajax
    javascript-时间戳
    关于Vue实例的生命周期created和mounted的区别
    ES6核心内容讲解
    jsonp跨域请求
    javascript-AJAX
  • 原文地址:https://www.cnblogs.com/rausen/p/4196757.html
Copyright © 2020-2023  润新知