BZOJ_1196_[HNOI2006]公路修建问题_kruskal+二分答案

Posted fcwww

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ_1196_[HNOI2006]公路修建问题_kruskal+二分答案相关的知识,希望对你有一定的参考价值。

BZOJ_1196_[HNOI2006]公路修建问题_kruskal+二分答案

题意:http://www.lydsy.com/JudgeOnline/problem.php?id=1196

分析:

先把所有路都拆成两条。

二分答案mid,把大于mid的边除去,优先加一级公路,判断能不能加进去k条。

代码:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <algorithm>
 4 using namespace std;
 5 #define N 10050
 6 struct A{
 7     int a,b,v;
 8 }e[N<<2];
 9 int n,m,k,fa[N],usex[N<<1],usey[N<<1];
10 int find(int x){
11     return fa[x]^x?fa[x]=find(fa[x]):x;    
12 }
13 bool check(int x){
14     for(int i=1;i<=n;i++)fa[i]=i;
15     int ne=0;
16     for(int i=1;i<=m;i++){
17         if(e[i].v>x)continue;
18         int dx=find(e[i].a),dy=find(e[i].b);
19         if(dx!=dy){
20             fa[dx]=dy;
21             ne++;if(ne==n-1)return 1;    
22         }
23     }if(ne<k)return 0;
24     for(int i=m+1;i<=2*m;i++){
25         if(e[i].v>x)continue;
26         int dx=find(e[i].a),dy=find(e[i].b);
27         if(dx!=dy){
28             fa[dx]=dy;ne++;if(ne==n-1)return 1;    
29         }
30     }return 0;
31 }
32 int main(){
33     scanf("%d%d%d",&n,&k,&m);m--;
34     int x,y,z,w;
35     for(int i=1;i<=m;i++){
36         scanf("%d%d%d%d",&x,&y,&z,&w);
37         e[i].a=e[i+m].a=x;
38         e[i].b=e[i+m].b=y;
39         e[i].v=z;e[i+m].v=w;
40     }
41     int l=0,r=1<<30;
42     while(l<r){
43         int mid=l+r>>1;
44         if(check(mid))r=mid;
45         else l=mid+1;    
46     }
47     printf("%d\n",l);
48     for(int i=1;i<=n;i++)fa[i]=i;
49     int ne=0;
50     for(int i=1;i<=m;i++){
51         if(e[i].v>l)continue;
52         int dx=find(e[i].a),dy=find(e[i].b);
53         if(dx!=dy){
54             fa[dx]=dy;
55             ne++;
56             usex[i]=1;
57         }
58     }
59     for(int i=m+1;i<=m+m;i++){
60         if(e[i].v>l)continue;
61         int dx=find(e[i].a),dy=find(e[i].b);
62         if(dx!=dy){
63             fa[dx]=dy;
64             ne++;
65             usey[i-m]=1;
66         }
67     }
68     for(int i=1;i<=m;i++){
69         if(usex[i])printf("%d 1\n",i);
70         else if(usey[i])printf("%d 2\n",i);    
71     }
72 }

 

以上是关于BZOJ_1196_[HNOI2006]公路修建问题_kruskal+二分答案的主要内容,如果未能解决你的问题,请参考以下文章

bzoj 1196: [HNOI2006]公路修建问题 二分+并查集

BZOJ1196 [HNOI2006] 公路修建问题

bzoj 1196: [HNOI2006]公路修建问题

bzoj1196hnoi2006公路修建问题

BZOJ 1196 HNOI2006 公路修建问题

BZOJ 1196 [HNOI2006]公路修建问题(二分答案+并查集)