zoukankan      html  css  js  c++  java
  • HDU 4253 Two Famous Companies

    Two Famous Companies

    Time Limit: 15000ms
    Memory Limit: 32768KB
    This problem will be judged on HDU. Original ID: 4253
    64-bit integer IO format: %I64d      Java class name: Main
     
    In China, there are two companies offering the Internet service for the people from all cities: China Telecom and China Unicom. They both are planning to build cables between cities. Obviously, the government wants to connect all the cities in minimum costs. So the minister of finance Mr. B wants to choose some of the cable plans from the two companies and calculate the minimum cost needed to connect all the cities. Mr. B knows that N-1 cables should be built in order to connect all N cities of China. For some honorable reason, Mr. B should choose K cables from the China Telecom and the rest N-1-K cables from the China Unicom. Your job is to help Mr. B determine which cables should be built and the minimum cost to build them. You may assume that the solution always exists.
     

    Input

    Each test case starts with a line containing the number of cities N (1 <= N <= 50,000), number of cable plans M (N-1 <= M <= 100,000) and the number of required cables from China Telecom K (0 <= K <= N-1). This is followed by M lines, each containing four integers a, b, c, x (0 <= a, b <= N-1, a != b, 1 <= c <= 100, x in {0,1} indicating the pair of cities this cable will connect, the cost to build this cable and the company this cable plan belongs to. x=0 denotes that the cable plan belongs to China Telecom and x=1 denotes that the cable plan is from China Unicom.
     

    Output

    For each test case, display the case number and the minimum cost of the cable building.
     

    Sample Input

    2 2 1
    0 1 1 1
    0 1 2 0
    2 2 0
    0 1 1 1
    0 1 2 0

    Sample Output

    Case 1: 2
    Case 2: 1
    Hint
    In the first case, there are two cable plans between the only two cities, one from China Telecom and one from China Unicom. Mr. B needs to choose the one from China Telecom to satisfy the problem requirement even the cost is higher. In the second case, Mr. B must choose the cable from China Unicom, which leads the answer to 1.

    Source

     
    解题:最小生成树+二分。很不错的一题。。。在某个公司的边上增加一个值,直到取到了该公司指定的数目的边。
     
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <algorithm>
     6 #include <climits>
     7 #include <vector>
     8 #include <queue>
     9 #include <cstdlib>
    10 #include <string>
    11 #include <set>
    12 #include <stack>
    13 #define LL long long
    14 #define pii pair<int,int>
    15 #define INF 0x3f3f3f3f
    16 using namespace std;
    17 const int maxn = 100010;
    18 struct arc{
    19     int u,v,w,id;
    20     arc(int uu = 0,int vv = 0,int ww = 0,int iid = 0){
    21         u = uu;
    22         v = vv;
    23         w = ww;
    24         id = iid;
    25     }
    26     bool operator<(const arc &tmp) const{
    27         return w < tmp.w;
    28     }
    29 };
    30 arc e[2][maxn];
    31 int uf[maxn],n,m,k,tot1,tot2,cost;
    32 int Find(int x){
    33     if(x == uf[x]) return x;
    34     return uf[x] = Find(uf[x]);
    35 }
    36 bool uset(int u,int v){
    37     int tx = Find(u);
    38     int ty = Find(v);
    39     if(tx != ty) uf[tx] = ty;
    40     return tx != ty;
    41 }
    42 bool check(int delta){
    43     int i,j,cnt;
    44     for(i = 0; i <= n; ++i) uf[i] = i;
    45     i = j = cnt = cost = 0;
    46     arc tmp;
    47     while(i < tot1 || j < tot2){
    48         if(e[0][i].w + delta <= e[1][j].w){
    49             tmp = e[0][i++];
    50             tmp.w += delta;
    51         }else tmp = e[1][j++];
    52         if(uset(tmp.u,tmp.v)){
    53             cost += tmp.w;
    54             if(!tmp.id) cnt++;
    55         }
    56     }
    57     return cnt >= k;
    58 }
    59 int main() {
    60     int u,v,w,id,cs = 1;
    61     while(~scanf("%d %d %d",&n,&m,&k)){
    62         for(int i = tot1 = tot2 = 0; i < m; ++i){
    63             scanf("%d %d %d %d",&u,&v,&w,&id);
    64             if(id) e[1][tot2++] = arc(u,v,w,id);
    65             else e[0][tot1++] = arc(u,v,w,id);
    66         }
    67         e[0][tot1].w = e[1][tot2].w = INF;
    68         sort(e[0],e[0]+tot1);
    69         sort(e[1],e[1]+tot2);
    70         int low = -100,high = 100,mid,delta;
    71         while(low <= high){
    72             mid = (low + high)>>1;
    73             if(check(mid)){
    74                 delta = mid;
    75                 low = mid + 1;
    76             }else high = mid - 1;
    77         }
    78         check(delta);
    79         printf("Case %d: %d
    ",cs++,cost - delta*k);
    80     }
    81     return 0;
    82 }
    View Code
     
  • 相关阅读:
    JavaScriptSerializer的使用, 今上午琢磨了半天, 小结一下.
    解决TextBox中, JS方法(DatePicker)改变Text内容后, 无法触发OnTextChanged事件的问题
    学习笔记Oracle操作总结
    学习笔记再次理解事件和委托
    Linux第一天接触, 安装CentOS后解决中文字体的问题
    jQuery验证客户端控件, 在提交表单时用MD5.js将密码变成密文
    学习笔记 缓存、动态页面静态化、网站优化
    学习笔记母板页、用户控件、第三方控件及视图状态管理
    学习笔记Javascript原型对象、this的5钟用法、原型继承、Caller和Callee的使用
    学习笔记元数据、程序集、GAC版本控制、属性(Attribute)、反射(利用.NET编译器实现表达式计算器)
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4032703.html
Copyright © 2011-2022 走看看