zoukankan      html  css  js  c++  java
  • uvalive 11865 Stream My Contest

    题意:

    有一个网络中心,和许多个城市,网络中心以及城市之间有若干条边,这些边有两个属性,最大带宽和修建费用。

    现在要用最多不超过C的费用修建网络,使得每个城市都有网络连接,最大化最小带宽。

    带宽限制是,一条边可以接受不大于自己最大值的带宽。

    边是有向边unidirectional

    思路:

    最大化最小值,那么考虑到用二分,但是这题应该有一个隐藏条件,那就是带宽越大,修建费用越高,这样才满足二分的条件。

    然后有向边,就用最小树形图的朱刘算法,复杂度为O(n^3),由于n的规模比较小,所以可以接受。

    注意,需要先特判输入中的最小带宽是否满足要求

    代码:

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <vector>
      4 #include <algorithm>
      5 using namespace std;
      6 
      7 const int N = 65;
      8 const int inf = 0x3f3f3f3f;
      9 
     10 int in[N],vis[N],pre[N],id[N];
     11 
     12 struct edge
     13 {
     14     int from,to,cost;
     15     
     16     edge(int a,int b,int c)
     17     {
     18         from = a;
     19         to = b;
     20         cost = c;
     21     }
     22 };
     23 
     24 struct node
     25 {
     26     int from,to,bd,cost;
     27     
     28     node(int a,int b,int c,int d)
     29     {
     30         from = a;
     31         to = b;
     32         bd = c;
     33         cost = d;
     34     }
     35 };
     36 
     37 vector<node> ns;
     38 vector<edge> es;
     39 
     40 int n,m,sumc;
     41 
     42 int meet(int lim)
     43 {
     44     es.clear();
     45     
     46     int root = 0;
     47     
     48     int res = 0;
     49     
     50     int tn = n;
     51     
     52     for (int i = 0;i < m;i++)
     53     {
     54         int a = ns[i].from,b = ns[i].to,c = ns[i].bd,d = ns[i].cost;
     55         
     56         if (c < lim) continue;
     57         
     58         es.push_back(edge(a,b,d));
     59     }
     60     
     61     while (1)
     62     {
     63         //printf("2333
    ");    
     64         
     65         memset(in,inf,sizeof(in));
     66         
     67         for (int i = 0;i < es.size();i++)
     68         {
     69             edge e = es[i];
     70             
     71             int to = e.to;
     72             
     73             if (e.from != e.to && e.cost < in[to])
     74             {
     75                 in[to] = e.cost;
     76                 pre[to] = e.from;
     77             }
     78         }
     79         
     80         for (int i = 0;i < tn;i++)
     81         {
     82             if (i != root && in[i] == inf)
     83                 return -1;
     84         }
     85         
     86         int cnt = 0;
     87         
     88         memset(id,-1,sizeof(id));
     89         memset(vis,-1,sizeof(vis));
     90         
     91         in[root] = 0;
     92         
     93         for (int i = 0;i < tn;i++)
     94         {
     95             res += in[i];
     96             
     97             int v = i;
     98             
     99             while (vis[v] != i && id[v] == -1 && v != root)
    100             {
    101                 vis[v] = i;
    102                 v = pre[v];
    103             }
    104             
    105             if (id[v] == -1 && v != root)
    106             {
    107                 for (int u = pre[v];u != v;u = pre[u])
    108                 {
    109                     id[u] = cnt;
    110                 }
    111                 
    112                 id[v] = cnt++;
    113             }
    114         }
    115         
    116         if (cnt == 0) break;
    117         
    118         for (int i = 0;i < tn;i++)
    119         {
    120             if (id[i] == -1) id[i] = cnt++;
    121         }
    122         
    123         for (int i = 0;i < es.size();i++)
    124         {
    125             int to = es[i].to;
    126             
    127             es[i].from = id[es[i].from];
    128             es[i].to = id[es[i].to];
    129             
    130             if (es[i].from != es[i].to)
    131             {
    132                 es[i].cost -= in[to];
    133             }
    134         }
    135         
    136         root = id[root];
    137         tn = cnt;
    138     }
    139     
    140     if (res > sumc) return -1;
    141     else return res;
    142 }
    143 
    144 int main()
    145 {
    146     int t;
    147     
    148     scanf("%d",&t);
    149     
    150     while (t--)
    151     {
    152         scanf("%d%d%d",&n,&m,&sumc);
    153         
    154         ns.clear();
    155         
    156         int mnb = inf,mxb = 0;
    157         
    158         for (int i = 0;i < m;i++)
    159         {
    160             int a,b,c,d;
    161             
    162             scanf("%d%d%d%d",&a,&b,&c,&d);
    163             
    164             ns.push_back(node(a,b,c,d));
    165             
    166             mxb = max(mxb,c);
    167             mnb = min(mnb,c);
    168         }
    169         
    170         if (meet(mnb) == -1)
    171         {
    172             printf("streaming not possible.
    ");
    173         }
    174         else
    175         {
    176             while (mxb - mnb > 1)
    177             {
    178                 //printf("***
    ");
    179                 int mid = (mxb + mnb) >> 1;
    180                 
    181                 if (meet(mid) != -1) mnb = mid;
    182                 else mxb = mid - 1;
    183             }
    184             
    185             while (meet(mnb+1) != -1) mnb++;
    186             
    187             printf("%d kbps
    ",mnb);
    188         }
    189     }
    190     
    191     return 0;
    192 }
  • 相关阅读:
    范式理论
    事务
    触发器练一练
    Javascript模块化编程(三):require.js的用法
    Javascript模块化编程(二):AMD规范
    Javascript模块化编程(一):模块的写法
    什么是比特币?这可能是最通俗易懂的答案了
    Apache服务器的Options 的 Indexes FollowSymLinks详解
    机器学习进阶-图像金字塔与轮廓检测-图像金字塔(拉普拉斯金字塔)
    机器学习进阶-图像金字塔与轮廓检测-图像金字塔-(**高斯金字塔) 1.cv2.pyrDown(对图片做向下采样) 2.cv2.pyrUp(对图片做向上采样)
  • 原文地址:https://www.cnblogs.com/kickit/p/8809006.html
Copyright © 2011-2022 走看看