zoukankan      html  css  js  c++  java
  • uva 11865(二分+最小树形图)

    题意:有向带权图中每一条边上有一个带宽和长度,你的任务是在图中找出树形图他的费用小于cost,且是树中最小带宽最大。

    思路:二分带宽+最小树形图。由于满足单调性(带宽范围越大花费越少)所以我们可以二分带宽然后求满足要求的边的最小树形图即可。

    代码如下:

      1 /**************************************************
      2  * Author     : xiaohao Z
      3  * Blog     : http://www.cnblogs.com/shu-xiaohao/
      4  * Last modified : 2014-02-07 13:53
      5  * Filename     : uva_11865.cpp
      6  * Description     : 
      7  * ************************************************/
      8 
      9 #include <iostream>
     10 #include <cstdio>
     11 #include <cstring>
     12 #include <cstdlib>
     13 #include <cmath>
     14 #include <algorithm>
     15 #include <queue>
     16 #include <stack>
     17 #include <vector>
     18 #include <set>
     19 #include <map>
     20 #define MP(a, b) make_pair(a, b)
     21 #define PB(a) push_back(a)
     22 
     23 using namespace std;
     24 typedef long long ll;
     25 typedef pair<int, int> pii;
     26 typedef pair<unsigned int,unsigned int> puu;
     27 typedef pair<int, double> pid;
     28 typedef pair<ll, int> pli;
     29 typedef pair<int, ll> pil;
     30 
     31 const int INF = 0x3f3f3f3f;
     32 const ll LINF = 0x3f3f3f3f3f3f3f3fLL;
     33 const double eps = 1E-6;
     34 const int LEN = 201;
     35 int pre[LEN], id[LEN], vis[LEN];
     36 ll in[LEN];
     37 struct E{ int fr, to, bmp;ll val;};
     38 E te[LEN*LEN];
     39 
     40 ll zhuliu(int root, int n, int m, E edge[]){
     41     ll ret = 0;
     42        int    u, v;
     43     while(1){
     44         for(int i=0; i<n; i++) in[i] = LINF;
     45         for(int i=0; i<m; i++)
     46             if(edge[i].fr != edge[i].to && edge[i].val < in[edge[i].to]){
     47                 pre[edge[i].to] = edge[i].fr;
     48                 in[edge[i].to] = edge[i].val;
     49             }
     50         for(int i=0; i<n; i++)
     51             if(i != root && in[i] == LINF) return LINF;
     52         int tn = 0;
     53         memset(id, -1, sizeof id);
     54         memset(vis, -1, sizeof vis);
     55         in[root] = 0;
     56         for(int i=0; i<n; i++){
     57             ret += in[i];
     58             v = i;
     59             while(vis[v] != i && id[v] == -1 && v != root){
     60                 vis[v] = i;
     61                 v = pre[v];
     62             }
     63             if(v != root && id[v] == -1){
     64                 for(int u=pre[v]; u!=v; u=pre[u])id[u] = tn;
     65                 id[v] = tn++;
     66             }
     67         }
     68         if(tn == 0) break;
     69         for(int i=0; i<n; i++) if(id[i] == -1)id[i] = tn++;
     70         for(int i=0; i<m; ){
     71             v = edge[i].to;
     72             edge[i].fr = id[edge[i].fr];
     73             edge[i].to = id[edge[i].to];
     74             if(edge[i].fr != edge[i].to) edge[i++].val -= in[v];
     75             else swap(edge[i], edge[--m]);
     76         }
     77         n = tn;
     78         root = id[root];
     79     }
     80     return ret;
     81 }
     82 
     83 int Makedge(int tbad, E edge[], int m){
     84     int top = 0;
     85     for(int i=0; i<m; i++)
     86        if(te[i].bmp >= tbad){
     87               edge[top].fr = te[i].fr;
     88            edge[top].to = te[i].to;
     89            edge[top++].val = te[i].val;
     90            }
     91     return top;
     92 }
     93 
     94 int main()
     95 {
     96 //    freopen("in.txt", "r", stdin);
     97     
     98     int T, n, m, cost;
     99     E edge[LEN*LEN];
    100     scanf("%d", &T);
    101     while(T--){
    102         int l = INF, r = 0;
    103         scanf("%d%d%d", &n, &m, &cost);
    104         for(int i=0; i<m; i++){
    105             scanf("%d%d%d%lld", &te[i].fr, &te[i].to, &te[i].bmp, &te[i].val);
    106             l = min(l, te[i].bmp);
    107             r = max(r, te[i].bmp);
    108         }
    109         Makedge(0, edge, m);
    110         if(zhuliu(0, n, m, edge) > cost) printf("streaming not possible.
    ");
    111         else {
    112             while(l < r){
    113                 int mid = (l+r+1)/2, tm = Makedge(mid, edge, m);
    114                 ll tans = zhuliu(0, n, tm, edge);
    115                 if(tans <= cost) l = mid;
    116                 else r = mid-1;
    117             }
    118             printf("%d kbps
    ", l);
    119         }
    120     }
    121     return 0;
    122 }
    View Code
    奔跑吧!少年!趁着你还年轻
  • 相关阅读:
    loj2042 「CQOI2016」不同的最小割
    loj2035 「SDOI2016」征途
    luogu2120 [ZJOI2007]仓库建设
    luogu3195 [HNOI2008]玩具装箱TOY
    51nod 1069 Nim游戏 + BZOJ 1022: [SHOI2008]小约翰的游戏John(Nim游戏和Anti-Nim游戏)
    HDU 5723 Abandoned country(最小生成树+边两边点数)
    BZOJ 1497: [NOI2006]最大获利(最大权闭合图)
    51nod 1615 跳跃的杰克
    SPOJ 839 Optimal Marks(最小割的应用)
    UVa 11107 生命的形式(不小于k个字符串中的最长子串)
  • 原文地址:https://www.cnblogs.com/shu-xiaohao/p/3539657.html
Copyright © 2011-2022 走看看