HDU 4786 Fibonacci Tree (2013成都1006题)

Fibonacci Tree

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 75    Accepted Submission(s): 38

Problem Description   Coach Pang is interested in Fibonacci numbers while Uncle Yang wants him to do some research on Spanning Tree. So Coach Pang decides to solve the following problem:

  Consider a bidirectional graph G with N vertices and M edges. All edges are painted into either white or black. Can we find a Spanning Tree with some positive Fibonacci number of white edges?

(Fibonacci number is defined as 1, 2, 3, 5, 8, … )  

 

Input   The first line of the input contains an integer T, the number of test cases.

  For each test case, the first line contains two integers N(1 <= N <= 10
5) and M(0 <= M <= 10
5).

  Then M lines follow, each contains three integers u, v (1 <= u,v <= N, u<> v) and c (0 <= c <= 1), indicating an edge between u and v with a color c (1 for white and 0 for black).  

 

Output   For each test case, output a line “Case #x: s”. x is the case number and s is either “Yes” or “No” (without quotes) representing the answer to the problem.  

 

Sample Input 2 4 4 1 2 1 2 3 1 3 4 1 1 4 0 5 6 1 2 1 1 3 1 1 4 1 1 5 1 3 5 1 4 2 1  

 

Sample Output Case #1: Yes Case #2: No  

 

Source
2013 Asia Chengdu Regional Contest  

 

 

只要白边优先和黑边优先两种顺序做两次最小生成树。

得到白边数量的区间,然后枚举斐波那契数列就可以了。

 

注意如果一开始是非连通的,输出NO

 

  1 /* ***********************************************
  2 Author        :kuangbin
  3 Created Time  :2013-11-16 14:14:50
  4 File Name     :E:\2013ACM\专题强化训练\区域赛\2013成都\1006.cpp
  5 ************************************************ */
  6 
  7 #include <stdio.h>
  8 #include <string.h>
  9 #include <iostream>
 10 #include <algorithm>
 11 #include <vector>
 12 #include <queue>
 13 #include <set>
 14 #include <map>
 15 #include <string>
 16 #include <math.h>
 17 #include <stdlib.h>
 18 #include <time.h>
 19 using namespace std;
 20 
 21 int f[1000010];
 22 
 23 struct Edge
 24 {
 25     int u,v,c;
 26 }edge[200010];
 27 int F[200010];
 28 int find(int x)
 29 {
 30     if(F[x] == -1)return x;
 31     return F[x] = find(F[x]);
 32 }
 33 
 34 bool cmp1(Edge a,Edge b)
 35 {
 36     return a.c < b.c;
 37 }
 38 bool cmp2(Edge a,Edge b)
 39 {
 40     return a.c > b.c;
 41 }
 42 int main()
 43 {
 44     //freopen("in.txt","r",stdin);
 45     //freopen("out.txt","w",stdout);
 46     int tot = 1;
 47     f[0] = 1;
 48     f[1] = 2;
 49     while(f[tot] <= 1000010)
 50     {
 51         f[tot+1] = f[tot] + f[tot-1];
 52         tot++;
 53     }
 54     int T;
 55     int iCase = 0;
 56     int n,m;
 57     scanf("%d",&T);
 58     while(T--)
 59     {
 60         iCase++;
 61         scanf("%d%d",&n,&m);
 62         for(int i = 0;i < m;i++)
 63             scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].c);
 64         sort(edge,edge+m,cmp1);
 65         memset(F,-1,sizeof(F));
 66         int cnt = 0;
 67         for(int i = 0;i < m;i++)
 68         {
 69             int t1 = find(edge[i].u);
 70             int t2 = find(edge[i].v);
 71             if(t1 != t2)
 72             {
 73                 F[t1] = t2;
 74                 if(edge[i].c == 1)cnt++;
 75             }
 76         }
 77         int Low = cnt;
 78         memset(F,-1,sizeof(F));
 79         sort(edge,edge+m,cmp2);
 80         cnt = 0;
 81         for(int i = 0;i < m;i++)
 82         {
 83             int t1 = find(edge[i].u);
 84             int t2 = find(edge[i].v);
 85             if(t1 != t2)
 86             {
 87                 F[t1] = t2;
 88                 if(edge[i].c == 1)cnt++;
 89             }
 90         }
 91         int High = cnt;
 92         bool ff = true;
 93         for(int i = 1;i <= n;i++)
 94             if(find(i) != find(1))
 95             {
 96                 ff = false;
 97                 break;
 98             }
 99         if(!ff)
100         {
101             printf("Case #%d: No\n",iCase);
102             continue;
103         }
104         bool flag = false;
105         for(int i = 0;i <= tot;i++)
106             if(f[i] >= Low && f[i] <= High)
107                 flag = true;
108         if(flag)
109             printf("Case #%d: Yes\n",iCase);
110         else printf("Case #%d: No\n",iCase);
111 
112     }
113     return 0;
114 }

 

 

 

 

 

 

    原文作者:算法小白
    原文地址: https://www.cnblogs.com/kuangbin/p/3429010.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞