zoukankan      html  css  js  c++  java
  • hdu4786 Fibonacci Tree(kruskal+并查集)

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

    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 <= 105) and M(0 <= M <= 105).
      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

    题目大意:

    给定一堆权值为0或1的边,问是否能组成一棵生成树,使得生成树的边权值之和为斐波那契数列上的数

    思路:

    先用并查集判断是不是连通图,如果不是直接为No

    边权值按从小到大的顺序排一遍,生成树求出最小值minn

    边权值按从大到小的顺序排一遍,生成树求出最大值maxn

    判断[minn,maxn]存不存在斐波那契数列上的数,存在Yes,不存在No(权值为1的边可以用多条权值为0的边去凑)

     1 #include <cstdio>
     2 #include <algorithm>
     3 using namespace std;
     4 
     5 int t,n,m,ca=0;
     6 const int MAX=1e5+5;
     7 struct Edge{
     8     int from,to,val;
     9 }edge[MAX];
    10 int fa[MAX],fib[MAX];
    11 
    12 void sol(){
    13     fib[1]=fib[2]=1;
    14     int bef=1,nxt=2,sum=bef+nxt;
    15     while(sum<MAX){
    16         fib[sum]=1;
    17         bef=nxt;
    18         nxt=sum;
    19         sum=bef+nxt;
    20     }
    21 }
    22 
    23 int find(int x){
    24     int k=x;
    25     while(fa[k]!=k)k=fa[k];
    26     int w=x,ww;
    27     while(fa[w]!=w){
    28         ww=fa[w];
    29         fa[w]=k;
    30         w=ww;
    31     }
    32     return k;
    33 }
    34 
    35 bool cmp1(Edge x,Edge y){
    36     return x.val<y.val;
    37 }
    38 
    39 bool cmp2(Edge x,Edge y){
    40     return x.val>y.val;
    41 }
    42 
    43 int kruskal(){
    44     int res=0;
    45     for(int i=1;i<=n;i++)fa[i]=i;
    46     for(int i=0,k=0;i<m&&k<n-1;i++,k++){
    47         int fx=find(edge[i].from),fy=find(edge[i].to);
    48         if(fx!=fy){
    49             fa[fx]=fy;
    50             res+=edge[i].val;
    51         }
    52     }
    53     return res;
    54 }
    55 
    56 int main(){
    57     sol();
    58     scanf("%d",&t);
    59     while(t--){
    60         scanf("%d%d",&n,&m);
    61         for(int i=1;i<=n;i++)fa[i]=i;
    62         for(int i=0;i<m;i++){
    63             scanf("%d%d%d",&edge[i].from,&edge[i].to,&edge[i].val);
    64             int fx=find(edge[i].from),fy=find(edge[i].to);
    65             if(fx!=fy){
    66                 fa[fx]=fy;
    67             }
    68         }
    69         int flag=1;
    70         int rt=find(1);
    71         for(int i=1;i<=n;i++){
    72             if(find(i)!=rt){
    73                 flag=0;
    74                 break;
    75             }
    76         }
    77         if(flag==0){
    78             printf("Case #%d: No
    ",++ca);
    79             continue;
    80         }
    81         sort(edge,edge+m,cmp1);
    82         int minn=kruskal();
    83         sort(edge,edge+m,cmp2);
    84         int maxn=kruskal();
    85         flag=0;
    86         for(int i=minn;i<=maxn;i++){
    87             if(fib[i]==1){
    88                 flag=1;
    89                 break;
    90             }
    91         }
    92         if(flag==1)printf("Case #%d: Yes
    ",++ca);
    93         else printf("Case #%d: No
    ",++ca);
    94     }
    95 }
  • 相关阅读:
    转发 GSLB概要和实现原理
    通过openresty && tengine && nginx 动态添加资源到 html 页面
    Terraform 多云管理工具
    vault key 管理工具
    fabio
    keycloak 了解
    访问交换机的三种方式
    LAN、WAN、WLAN的区别
    浅谈团队贡献分如何分配
    Java程序性能分析工具Java VisualVM(Visual GC)—程序员必备利器
  • 原文地址:https://www.cnblogs.com/ChangeG1824/p/11679955.html
Copyright © 2011-2022 走看看