bzoj1196 [HNOI2006]公路修建问题

题目链接

二分答案+kruskal最小生成树判断

二分费用,用满足费用要求的边来生成树,判断能否生成树

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<string>
 5 #include<cstring>
 6 #include<cmath>
 7 #include<algorithm>
 8 #include<ctime>
 9 #include<queue>
10 #include<stack>
11 #include<map>
12 #include<set>
13 using namespace std;
14 struct bian
15 {
16     int u,v,c1,c2;
17 }bi[20020];
18 int getint()
19 {
20     int ret=0;char ch=getchar();
21     while(ch<'0'||ch>'9')ch=getchar();
22     while(ch>='0'&&ch<='9')ret*=10,ret+=ch-'0',ch=getchar();
23     return ret;
24 }
25 int n,k,m,ans,fa[10010];
26 int find(int x)
27 {
28     return x==fa[x]?x:fa[x]=find(fa[x]);
29 }
30 bool check(int x)
31 {
32     int sum=0;
33     for(int i=1;i<=n;i++)fa[i]=i;
34     for(int i=1;i<=m;i++)
35     {
36         if(bi[i].c1>x)continue;
37         int q=find(bi[i].u),w=find(bi[i].v);
38         if(q!=w)
39             fa[q]=w,sum++;
40     }
41     if(sum<k)return 0;
42     for(int i=1;i<=m;i++)
43     {
44         if(bi[i].c2>x)continue;
45         int q=find(bi[i].u),w=find(bi[i].v);
46         if(q!=w)
47             fa[q]=w,sum++;
48     }
49     if(sum!=n-1)return 0;
50     return 1;
51 }
52 int main()
53 {
54     n=getint(),k=getint(),m=getint();m--;
55     for(int i=1;i<=m;i++)
56         bi[i].u=getint(),bi[i].v=getint(),bi[i].c1=getint(),bi[i].c2=getint();
57     int l=1,r=30000;
58     while(l<=r)
59     {
60         int mid=(l+r)>>1;
61         if(check(mid))ans=mid,r=mid-1;
62         else l=mid+1;
63     }
64     printf("%d",ans);
65     return 0;
66 }

 

posted @ 2016-01-22 16:21  HugeGun  阅读(178)  评论(0编辑  收藏  举报