• bzoj1196[HNOI2006]公路修建问题


    bzoj1196[HNOI2006]公路修建问题

    题意:

    修n-1条公路将n个点连通,每个点可建一级公路也可建二级公路,要求一级公路必须有k条,要求花费最多的公路花费最少。

    题解:

    首先二分最大花费,接着判定:先在不产生环的前提下(用并查集维护)让每条路尽量修一级公路,如果最后无法构成树则考虑修二级公路。

    代码:

     1 #include <cstdio> 
     2 #include <cstring>
     3 #include <algorithm>
     4 #define inc(i,j,k) for(int i=j;i<=k;i++)
     5 #define maxn 10500
     6 using namespace std;
     7 
     8 int n,k,m,u[maxn*2],v[maxn*2],c1[maxn*2],c2[maxn*2],mx,fa[maxn],cnt;
     9 int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
    10 bool check(int lim){
    11     inc(i,1,n)fa[i]=i; cnt=0;
    12     inc(i,1,m)if(c1[i]<=lim){
    13         int x=find(u[i]),y=find(v[i]); if(x==y)continue; fa[y]=x; cnt++;
    14     }
    15     if(cnt<k)return 0;
    16     inc(i,1,m)if(c2[i]<=lim){
    17         int x=find(u[i]),y=find(v[i]); if(x==y)continue; fa[y]=x; cnt++;
    18     }
    19     if(cnt<n-1)return 0; return 1;
    20 }
    21 int main(){
    22     scanf("%d%d%d",&n,&k,&m); mx=0;
    23     inc(i,1,m-1)scanf("%d%d%d%d",&u[i],&v[i],&c1[i],&c2[i]),mx=max(mx,c1[i]),mx=max(mx,c2[i]);
    24     int l=0,r=mx,ans;
    25     while(l<=r){
    26         int mid=(l+r)>>1;
    27         if(check(mid))ans=mid,r=mid-1;else l=mid+1;
    28     }
    29     printf("%d",ans); return 0;
    30 }

    20160531

  • 相关阅读:
    The Tamworth Two chapter 2.4
    USACO Controlling Companies chapter 2.3 已跪
    非递归快排
    链表二路归并
    Money Systems chapter 2.3 dp
    #pragma pack与sizeof union
    快慢指针
    12
    11
    10
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/5689438.html
Copyright © 2020-2023  润新知