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

    二分答案
    验证有一种贪心的思想,就是如果这条路的c1比二分的值还小,那就要果断选择一级公路。
    搜过一遍后,如果可供选择的一级公路小于k,就可以直接返回否了。
    接下来继续选择,如果可以选到n-1条路,就可以,否则就不可以。
    选择道路时,选择的一定是不在一个集合里及不连通的,要用并查集优化。
     
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    using namespace std;
     
    #define N 100010
     
    struct Node
    {
        int x,y,c1,c2;
    }a[N<<2];
     
    int n,k,m;
    int f[N];
     
    int find(int x)
    {
        return x==f[x] ? f[x] : f[x]=find(f[x]);
    }
     
    int work(int d)
    {
        int ans=0;
        for (int i=1;i<=n;i++)
            f[i]=i;
        for (int i=1;i<=m;i++)
            if (a[i].c1<=d)
            {
                int r1=find(a[i].x),r2=find(a[i].y);
                if (r1!=r2)
                    f[r1]=r2,ans++;
            }
        if (ans<k)
            return false;
        for (int i=1;i<=m;i++)
            if (a[i].c2<=d)
            {
                int r1=find(a[i].x),r2=find(a[i].y);
                if (r1!=r2)
                    f[r1]=r2,ans++;
            }
        if (ans==n-1)
            return true;
        else
            return false;
    }
     
    int main()
    {
        scanf("%d%d%d",&n,&k,&m);
        for (int i=1;i<=m;i++)
            scanf("%d%d%d%d",&a[i].x,&a[i].y,&a[i].c1,&a[i].c2);
        int l=0,r=N;
        while (l<r)
        {
            int mid=(l+r)>>1;
            if (work(mid))
                r=mid;
            else
                l=mid+1;
        }
        if (work(l))
            printf("%d",l);
        else
            printf("%d",r);
        return 0;
    }
    

      

  • 相关阅读:
    Java中一对多映射关系(转)
    java映射一对一关系 (转)
    如何创建JUnit
    Java数组转置
    get与post方法(吴老师整理)
    后台获得数据
    JDK1.8的安装与卸载
    使用JSP输出九九乘法表
    foreach
    匿名内部类
  • 原文地址:https://www.cnblogs.com/yangjiyuan/p/5320959.html
Copyright © 2011-2022 走看看