BZOJ 1083 [SCOI2005]繁忙的都市

这个经典的设问形式你难道没有心动么?

这不是在提示你二分么?

二分边权,然后并查集判定连通性,因为连通了一定会有最小生成树

奥,第一问的答案是n-1应该没问题吧,

View Code
 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <algorithm>
 5 #include <cstdio>
 6 
 7 #define N 1000
 8 #define M 100000
 9 
10 using namespace std;
11 
12 struct EG
13 {
14     int a,b,c;
15 }eg[M];
16 
17 int fa[N],n,m,ans;
18 
19 inline bool cmp(const EG &a,const EG &b)
20 {
21     return a.c<b.c;
22 }
23 
24 inline int findfa(int x)
25 {
26     if(fa[x]!=x) fa[x]=findfa(fa[x]);
27     return fa[x];
28 }
29 
30 inline void read()
31 {
32     scanf("%d%d",&n,&m);
33     for(int i=1;i<=m;i++)
34         scanf("%d%d%d",&eg[i].a,&eg[i].b,&eg[i].c);
35 }
36 
37 inline bool check(int len)
38 {
39     for(int i=1;i<=n;i++) fa[i]=i;
40     for(int i=1;i<=m;i++)
41         if(eg[i].c<=len)
42         {
43             if(findfa(eg[i].a)!=findfa(eg[i].b))
44                 fa[findfa(eg[i].a)]=findfa(eg[i].b);
45         }
46     for(int i=2;i<=n;i++)
47         if(findfa(i)!=findfa(1)) return false;
48     return true;
49 }
50 
51 inline void go()
52 {
53     sort(eg+1,eg+1+m,cmp);
54     int l=1,r=m,mid;
55     while(l<=r)
56     {
57         mid=(l+r)>>1;
58         if(check(eg[mid].c)) ans=eg[mid].c,r=mid-1;
59         else l=mid+1;
60     }
61     printf("%d %d\n",n-1,ans);
62 }
63 
64 int main()
65 {
66     read();
67     go();
68     return 0;
69 }
原文地址:https://www.cnblogs.com/proverbs/p/2867082.html