zoukankan      html  css  js  c++  java
  • BZOJ1196 [HNOI2006] 公路修建问题

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1196

    Description

    OI island是一个非常漂亮的岛屿,自开发以来,到这儿来旅游的人很多。然而,由于该岛屿刚刚开发不久,所以那里的交通情况还是很糟糕。所以,OIER Association组织成立了,旨在建立OI island的交通系统。 OI island有n个旅游景点,不妨将它们从1到n标号。现在,OIER Association需要修公路将这些景点连接起来。一条公路连接两个景点。公路有,不妨称它们为一级公路和二级公路。一级公路上的车速快,但是修路的花费要大一些。 OIER Association打算修n-1条公路将这些景点连接起来(使得任意两个景点之间都会有一条路径)。为了保证公路系统的效率, OIER Association希望在这n-1条公路之中,至少有k条(0≤k≤n-1)一级公路。OIER Association也不希望为一条公路花费的钱。所以,他们希望在满足上述条件的情况下,花费最多的一条公路的花费尽可能的少。而你的任务就是,在给定一些可能修建的公路的情况下,选择n-1条公路,满足上面的条件。

    Input

    第一行有三个数n(1≤n≤10000),k(0≤k≤n-1),m(n-1≤m≤20000),这些数之间用空格分开。 N和k如前所述,m表示有m对景点之间可以修公路。以下的m-1行,每一行有4个正整数a,b,c1,c2 (1≤a,b≤n,a≠b,1≤c2≤c1≤30000)表示在景点a与b 之间可以修公路,如果修一级公路,则需要c1的花费,如果修二级公路,则需要c2的花费。

    Output

    一个数据,表示花费最大的公路的花费。

    这道题貌似之前的某一次NOIP模拟赛有,终于学会了……

    二分最大边即可

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cstring>
     5 #define rep(i,l,r) for(int i=l; i<=r; i++)
     6 #define clr(x,y) memset(x,y,sizeof(x))
     7 #define travel(x) for(Edge *p=last[x]; p; p=p->pre)
     8 using namespace std;
     9 const int INF = 0x3f3f3f3f;
    10 const int maxn = 10010;
    11 inline int read(){
    12     int ans = 0, f = 1;
    13     char c = getchar();
    14     for(; !isdigit(c); c = getchar())
    15     if (c == '-') f = -1;
    16     for(; isdigit(c); c = getchar())
    17     ans = ans * 10 + c - '0';
    18     return ans * f;
    19 }
    20 struct Edge{
    21     int from,to,c1,c2;
    22 }edge[20010];
    23 int n,m,k,cnt=0,fa[maxn];
    24 int getfa(int x){
    25     return x == fa[x] ? x : fa[x] = getfa(fa[x]);
    26 }
    27 bool judge(int x){
    28     rep(i,1,n) fa[i] = i;
    29     int cnt = 0;
    30     rep(i,1,m-1){
    31         if (edge[i].c1 > x) continue;
    32         int a = getfa(edge[i].from); int b = getfa(edge[i].to);
    33         if (a != b){
    34             fa[a] = b; cnt++;
    35         }
    36     }
    37     if (cnt < k) return 0;
    38     rep(i,1,m-1){
    39         if (edge[i].c2 > x) continue;
    40         int a = getfa(edge[i].from); int b = getfa(edge[i].to);
    41         if (a != b){
    42             fa[a] = b; cnt++;
    43         }
    44     }
    45     if (cnt < n-1) return 0;
    46     return 1;
    47 }
    48 int main(){
    49     n = read(); k = read(); m = read();
    50     rep(i,1,m-1){
    51         edge[++cnt].from = read(); edge[cnt].to = read();
    52         edge[cnt].c1 = read(); edge[cnt].c2 = read();
    53     }
    54     int l = 1, r = 30000, ans;
    55     while (l <= r){
    56         int mid = (l + r) >> 1;
    57         if (judge(mid)) ans = mid, r = mid - 1;
    58         else l = mid + 1;
    59     }
    60     printf("%d
    ",ans);
    61     return 0;
    62 }
    View Code
  • 相关阅读:
    hive与hbase整合
    待重写
    hive DML
    【知识强化】第六章 总线 6.1 总线概述
    【知识强化】第五章 中央处理器 5.1 CPU的功能和基本结构
    【知识强化】第四章 指令系统 4.3 CISC和RISC的基本概念
    【知识强化】第四章 指令系统 4.2 指令寻址方式
    【知识强化】第四章 指令系统 4.1 指令格式
    【知识强化】第三章 存储系统 3.6 高速缓冲存储器
    【知识强化】第三章 存储系统 3.5 双口RAM和多模块存储器
  • 原文地址:https://www.cnblogs.com/jimzeng/p/bzoj1196.html
Copyright © 2011-2022 走看看