Hdu--4876(MST,变形)

2014-11-06 22:58:13

思路:首先尽量用黑边来生成树,然后尽量用白边来生成树。这样就求出了生成树内白边数量的最小可能值min和最大可能值max,那么min~max之间的值都是能取到的。(具体证明不是彻底懂)

   注意:判图连通性用并查集时,判断所有点的祖先是相同的,找每个点的祖先时一定要找到最祖先,用Find()函数,切记!

  1 /*************************************************************************
  2     > File Name: 4786.cpp
  3     > Author: Nature
  4     > Mail: 564374850@qq.com 
  5     > Created Time: Thu 06 Nov 2014 08:00:18 PM CST
  6 ************************************************************************/
  7 
  8 #include <cstdio>
  9 #include <cstring>
 10 #include <cstdlib>
 11 #include <cmath>
 12 #include <vector>
 13 #include <map>
 14 #include <set>
 15 #include <stack>
 16 #include <queue>
 17 #include <iostream>
 18 #include <algorithm>
 19 using namespace std;
 20 #define lp (p << 1)
 21 #define rp (p << 1|1)
 22 #define getmid(l,r) (l + (r - l) / 2)
 23 #define MP(a,b) make_pair(a,b)
 24 typedef long long ll;
 25 const int INF = 1 << 30;
 26 const int maxn = 100010;
 27 
 28 int T,N,M,ans;
 29 int fa[maxn];
 30 int fib[30];
 31 struct node{
 32     int u,v,c;
 33 }e[maxn];
 34 
 35 void Pre(){
 36     fib[0] = 1;
 37     fib[1] = 1;
 38     for(int i = 2; i <= 25; ++i)
 39         fib[i] = fib[i - 1] + fib[i - 2];
 40 }
 41 
 42 int Find(int x){
 43     return fa[x] == x ? x : fa[x] = Find(fa[x]);
 44 }
 45 
 46 void Union(int a,int b){
 47     int x = Find(a);
 48     int y = Find(b);
 49     if(x != y)
 50         fa[y] = x;
 51 }
 52 
 53 void Kruskal(){
 54     for(int i = 1; i <= N; ++i)
 55         fa[i] = i;
 56     for(int i = 1; i <= M; ++i){
 57         int x = Find(e[i].u);
 58         int y = Find(e[i].v);
 59         if(x != y){
 60             fa[y] = x;
 61             if(e[i].c == 1)
 62                 ++ans;
 63         }
 64     }
 65 }
 66 
 67 bool cmp1(node a,node b){
 68     return a.c > b.c;
 69 }
 70 
 71 bool cmp2(node a,node b){
 72     return a.c < b.c;
 73 }
 74 
 75 int main(){
 76     Pre();
 77     int a,b,c;
 78     scanf("%d",&T);
 79     for(int Case = 1; Case <= T; ++Case){
 80         scanf("%d%d",&N,&M);
 81         printf("Case #%d: ",Case);
 82         for(int i = 1; i <= N; ++i)
 83             fa[i] = i;
 84         for(int i = 1; i <= M; ++i){
 85             scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].c);
 86             Union(e[i].u,e[i].v);
 87         }
 88         if(M < N - 1){
 89             printf("No\n");
 90             continue;
 91         }
 92         int anc = Find(1),flag = 1;
 93         for(int i = 2; i <= N; ++i){
 94             if(Find(i) != anc){
 95                 flag = 0;
 96                 break;
 97             }
 98         }
 99         if(!flag){
100             printf("No\n");
101             continue;
102         }
103         int bot,top;
104         sort(e + 1,e + M + 1,cmp1);
105         ans = 0;
106         Kruskal();
107         top = ans;
108 
109         sort(e + 1,e + M + 1,cmp2);
110         ans = 0;
111         Kruskal();
112         bot = ans;
113         
114         flag = 0;
115         //printf("%d %d\n",bot,top);
116         for(int i = 1; i <= 25; ++i){
117             if(fib[i] >= bot && fib[i] <= top){
118                 flag = 1;
119                 break;
120             }
121         }
122         if(flag) printf("Yes\n");
123         else printf("No\n");
124     }
125     return 0;
126 }

 

posted @ 2014-11-06 23:06  Naturain  阅读(133)  评论(0编辑  收藏  举报