BZOJ 1196 HNOI2006 公路修建问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 1196 HNOI2006 公路修建问题相关的知识,希望对你有一定的参考价值。
一眼可以看出来最小生成树,但需要仔细思考。
如果去掉所谓的1级公路数量限制,单独思考 “花费最多的一条公路的花费尽可能的少”这个问题。
那么毫无疑问的需要二分。
多了一个1级公路,算法只需要吧1级公路和2级公路分开跑最小生成树就可以了。
#include <cstdio> #include <algorithm> #include <cstring> struct node{ int u,v,w1,w2; }Edge[52222]; int fa[12222]; int n,m,k,l=0,r=50000,mid; int x,y,w1,w2; bool CMP1(const node &a,const node &b){ return a.w1<b.w1; } bool CMP2(const node &a,const node &b){ return a.w2<b.w2; } int findfa(int x){ if(fa[x]!=x) return fa[x]=findfa(fa[x]); return fa[x]; } bool Can(int x){ std::sort(Edge+1,Edge+m,CMP1); int tot = 0; for(int i=1;tot<k;i++){ if(Edge[i].w1 > x || i > m-1) return false; int fx = findfa(Edge[i].u); int fy = findfa(Edge[i].v); if(fx!=fy){ fa[fx]=fy; tot++; } } std::sort(Edge+1,Edge+m,CMP2); tot = 0; for(int i=1;tot<n-k-1;i++){ if(Edge[i].w2 > x || i > m-1) return false; int fx = findfa(Edge[i].u); int fy = findfa(Edge[i].v); if(fx!=fy){ fa[fx]=fy; tot++; } } return true; } int main(){ scanf("%d%d%d",&n,&k,&m); for(int i=1;i<m;++i){ scanf("%d%d%d%d",&x,&y,&w1,&w2); Edge[i].u=x; Edge[i].v=y; Edge[i].w1=w1; Edge[i].w2=w2; } while(l<r){ for(int i=1;i<=n;i++) fa[i]=i; mid = (l+r)>>1; if( Can(mid) ) r=mid; else l = mid+1; } printf("%d\n",l); return 0; }
以上是关于BZOJ 1196 HNOI2006 公路修建问题的主要内容,如果未能解决你的问题,请参考以下文章