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 }

 

 

你可能感兴趣的:(ZOJ)