BZOJ 2654tree
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 2654tree相关的知识,希望对你有一定的参考价值。
Description
给你一个无向带权连通图,每条边是黑色或白色。让你求一棵最小权的恰好有need条白色边的生成树。
题目保证有解。
Input
第一行V,E,need分别表示点数,边数和需要的白色边数。
接下来E行
每行s,t,c,col表示这边的端点(点从0开始标号),边权,颜色(0白色1黑色)。
Output
一行表示所求生成树的边权和。
Sample Input
2 2 1
0 1 1 1
0 1 2 0
0 1 1 1
0 1 2 0
Sample Output
2
HINT
数据规模和约定
0:V<=10
1,2,3:V<=15
0,..,19:V<=50000,E<=100000
所有数据边权为[1,100]中的正整数。
orz 王梦迪大神
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 const int N=50010; 5 struct ee{int x,y,w,c;}e[N*2]; 6 int fa[N]; 7 int ans,E,V,need,tot; 8 int root(int x){ 9 if(fa[x]==x) return x; 10 fa[x]=root(fa[x]);return fa[x]; 11 } 12 13 bool cmp(ee a,ee b){ 14 if(a.w==b.w) return a.c<b.c; 15 return a.w<b.w; 16 } 17 18 int kls(){ 19 tot=0;int sum=0,num=0; 20 for(int i=0;i<V;i++) fa[i]=i; 21 for(int i=1;i<=E&&sum<V-1;i++){ 22 int xx=root(e[i].x),yy=root(e[i].y); 23 if(xx!=yy) fa[xx]=yy,sum++,tot+=e[i].w,num+=(e[i].c==0); 24 } 25 return num; 26 } 27 int main(){ 28 scanf("%d%d%d",&V,&E,&need); 29 int s,t,w,c; 30 for (int i=1;i<=E;i++){ 31 scanf("%d%d%d%d",&s,&t,&w,&c); 32 e[i].x=s;e[i].y=t;e[i].w=w;e[i].c=c; 33 } 34 int l=-100,r=100; 35 while(l<=r){ 36 int mid=(l+r)>>1; 37 for (int i=1;i<=E;i++) if(e[i].c==0)e[i].w+=mid; 38 sort(e+1,e+1+E,cmp); 39 int h=kls(); 40 if(h>=need) ans=(tot-need*mid),l=mid+1;else r=mid-1; 41 //ans这里要注意一下,1wa 42 for (int i=1;i<=E;i++) if(e[i].c==0)e[i].w-=mid; 43 } 44 printf("%d",ans); 45 }
以上是关于BZOJ 2654tree的主要内容,如果未能解决你的问题,请参考以下文章