首先计算图的联通情况,如果图本身不联通一定不会出现生成树,输出"NO",之后清空,加白边,看最多能加多少条,清空,加黑边,看能加多少条,即可得白边的最大值与最小值,之后判断Fibonacci数是否在这两个之间,如果是输出yes,否则no。
然而,,然而,,我看的题解有问题!!!!!调了俩小时愣是没找出错误来,,然后把题解交了发现过不了,,,,真是够了。,。,。,
第二天上午终于A了,,满分程序:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 struct data { 6 int x1; 7 int y1; 8 int z1; 9 }; 10 const int maxn = 200000 + 500; 11 int father[maxn]; 12 int f[maxn]; 13 data p[maxn]; 14 int T; 15 int n, m; 16 17 bool cmp(data aa, data bb) { 18 return (aa.z1 < bb.z1); 19 } 20 21 int getfather(int x) { 22 if (father[x] == x) return x; 23 return (father[x] = getfather(father[x])); 24 } 25 26 bool solve (void) { 27 int cur = n; 28 for (int i = 1; i <= m; i++) { 29 int tx = getfather(p[i].x1); 30 int ty = getfather(p[i].y1); 31 if (tx != ty) { 32 father[tx] = ty; 33 cur--; 34 } 35 } 36 if (cur > 1) return 1; 37 return 0; 38 } 39 40 int main () { 41 f[1] = 1; 42 f[2] = 1; 43 for (int i = 3; i <= 40; i++) { 44 f[i] = f[i-1] + f[i-2]; 45 } 46 scanf("%d", &T); 47 for (int kase = 1; kase <= T; kase++) { 48 printf("Case #%d: ", kase); 49 scanf("%d %d", &n, &m); 50 for (int i = 1; i <= n; i++) father[i] = i; 51 for (int i = 1; i <= m; i++) scanf("%d %d %d", &p[i].x1, &p[i].y1, &p[i].z1); 52 std :: sort(p + 1, p + m + 1, cmp); 53 if (solve()) printf("No "); 54 else { 55 for (int i = 1; i <= n; i++) father[i] = i; 56 int smin = 0; 57 for (int i = 1; i <= m; i++) { 58 int tx = getfather(p[i].x1); 59 int ty = getfather(p[i].y1); 60 if (tx != ty) { 61 father[tx] = ty; 62 if (p[i].z1 == 1) smin++; 63 } 64 } 65 int smax = 0; 66 for (int i = 1; i <= n; i++) father[i] = i; 67 for (int i = m; i >= 1; i--) { 68 int tx = getfather(p[i].x1); 69 int ty = getfather(p[i].y1); 70 if (tx != ty) { 71 father[tx] = ty; 72 if (p[i].z1 == 1) smax++; 73 } 74 } 75 bool flag = 0; 76 for (int i = 1; i <= 40; i++) 77 if (smin <= f[i] && smax >= f[i]) { 78 flag = 1; 79 break; 80 } 81 if (flag) printf("Yes "); 82 else printf("No "); 83 } 84 } 85 return 0; 86 }