• 1196/P2323: [HNOI2006]公路修建问题


    1196: [HNOI2006]公路修建问题

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 2191  Solved: 1258

    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

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

    Sample Input

    10 4 20
    3 9 6 3
    1 3 4 1
    5 3 10 2
    8 9 8 7
    6 8 8 3
    7 1 3 2
    4 9 9 5
    10 8 9 1
    2 6 9 1
    6 7 9 8
    2 6 2 1
    3 8 9 5
    3 2 9 6
    1 6 10 3
    5 6 3 1
    2 7 6 1
    7 8 6 2
    10 9 2 1
    7 1 10 2

    Sample Output

    5

    HINT

     

    Source

     只需要输出最小的值,二分答案即可。

     1 #include<cstdio>
     2 
     3 const int MAXN = 10100;
     4 struct Edge{
     5     int x,y,c1,c2;
     6     bool p1,p2;
     7 }e[50100];
     8 int fa[MAXN];
     9 int n,m,k,ans;
    10 int find(int x)
    11 {
    12     return x==fa[x]?x:fa[x]=find(fa[x]);
    13 }
    14 bool work(int x)
    15 {
    16     int cnt = 0;
    17     for (int i=1; i<=n; ++i) fa[i] = i;
    18     for (int i=1; i<=m; ++i)
    19     {
    20         if (e[i].c1>x) continue ;
    21         int rx = find(e[i].x);
    22         int ry = find(e[i].y);
    23         if (rx!=ry)
    24         {
    25             cnt++;
    26             fa[rx] = ry;
    27         }
    28     }
    29     if (cnt<k) return false;
    30     for (int i=1; i<=m; ++i)
    31     {
    32         if (e[i].c2>x) continue ;
    33         int rx = find(e[i].x);
    34         int ry = find(e[i].y);
    35         if (rx!=ry)
    36         {
    37             cnt++;
    38             fa[rx] = ry;
    39         }
    40     }
    41     if (cnt!=n-1) return false ;
    42     return true;
    43 }
    44 int main()
    45 {
    46     scanf("%d%d%d",&n,&k,&m);
    47     for (int i=1; i<=m; ++i)
    48         scanf("%d%d%d%d",&e[i].x,&e[i].y,&e[i].c1,&e[i].c2);
    49     int l = 0, r = 30000;
    50     while (l<=r)
    51     {
    52         int mid = (l+r)>>1;
    53         if (work(mid))
    54         {
    55             r = mid-1;
    56             ans = mid;
    57         }
    58         else l = mid+1;
    59     }
    60     printf("%d",ans);
    61     return 0;
    62 }

    洛谷上是这样的:

    P2323 [HNOI2006]公路修建问题

    题目描述

    输入输出格式

    输入格式:

    在实际评测时,将只会有m-1行公路

    输出格式:

    输入输出样例

    输入样例#1:
    4 2 5
    1 2 6 5
    1 3 3 1
    2 3 9 4
    2 4 6 1
    3 4 4 2
    输出样例#1:
    4
    2 1
    3 2
    5 1
    输入样例#2:
    4 1 5
    1 2 6 5
    1 3 3 1
    2 3 9 4
    2 4 6 1
    3 4 4 3
    输出样例#2:
    3
    2 1
    4 2
    5 2

    大多一个样,只是要输出道路,稍微改了一下。

     1 #include<cstdio>
     2 
     3 const int MAXN = 10100;
     4 struct Edge{
     5     int x,y,c1,c2;
     6     bool p1,p2;
     7 }e[50100];
     8 int fa[MAXN];
     9 int n,m,k,ans;
    10 int find(int x)
    11 {
    12     return x==fa[x]?x:fa[x]=find(fa[x]);
    13 }
    14 bool work(int x)
    15 {
    16     int cnt = 0;
    17     for (int i=1; i<=n; ++i) fa[i] = i;
    18     for (int i=1; i<=m; ++i)
    19     {
    20         e[i].p1 = false ;
    21         if (e[i].c1>x) continue ;
    22         int rx = find(e[i].x);
    23         int ry = find(e[i].y);
    24         if (rx!=ry)
    25         {
    26             cnt++;
    27             fa[rx] = ry;
    28             e[i].p1 = true;
    29         }
    30     }
    31     if (cnt<k) return false;
    32     for (int i=1; i<=m; ++i)
    33     {
    34         e[i].p2 = false;
    35         if (e[i].c2>x) continue ;
    36         int rx = find(e[i].x);
    37         int ry = find(e[i].y);
    38         if (rx!=ry)
    39         {
    40             cnt++;
    41             fa[rx] = ry;
    42             e[i].p2 = true;
    43         }
    44     }
    45     if (cnt!=n-1) return false ;
    46     return true;
    47 }
    48 int main()
    49 {
    50     scanf("%d%d%d",&n,&k,&m);
    51     for (int i=1; i<=m; ++i)
    52         scanf("%d%d%d%d",&e[i].x,&e[i].y,&e[i].c1,&e[i].c2);
    53     int l = 0, r = 30000;
    54     while (l<=r)
    55     {
    56         int mid = (l+r)>>1;
    57         if (work(mid))
    58         {
    59             r = mid-1;
    60             ans = mid;
    61         }
    62         else l = mid+1;
    63     }
    64     work(ans);    //重新计算一遍 
    65     printf("%d
    ",ans);
    66     for (int i=1; i<=m; ++i)
    67     {
    68         if (e[i].p1) printf("%d %d
    ",i,1);
    69         if (e[i].p2) printf("%d %d
    ",i,2);
    70     }
    71     return 0;
    72 }
  • 相关阅读:
    C# 多线程Thread.IsBackground=True的作用
    JS 判断用户设备 移动端或桌面端
    VSCode 代码格式化 快捷键
    PHP 根据 IP 获取定位数据
    C# 将文本写入到文件
    C# 读取文件内容
    PHP 美化输出数组
    VSCode 设置 Tab 空格
    custom post types 404 Page Error
    [已解决] wordpress 修改 permalink 后 页面 404 问题
  • 原文地址:https://www.cnblogs.com/mjtcn/p/7091436.html
Copyright © 2020-2023  润新知