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 }