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\n"); 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.\n"); 173 } 174 else 175 { 176 while (mxb - mnb > 1) 177 { 178 //printf("***\n"); 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\n",mnb); 188 } 189 } 190 191 return 0; 192 }
康复训练中~欢迎交流!