zoukankan      html  css  js  c++  java
  • HDU 4786 最小生成树变形 kruscal(13成都区域赛F)

    Fibonacci Tree

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


    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
     
    Source
     
    题意:N个顶点,M条边,每条边或为白色或为黑色( 1 or 0 ),问有没有用是斐波那契数的数目的白色边构成一棵生成树
    题解:N个顶点构成的生成树有N-1条边 ,首先判断能否能构成生成树,图是否是联通的,无法构成则输出No
    先使用所有的黑边 不断加边,看最多能使用多少条黑边使得不形成环 求得白边的使用的数量的下界
    然后再使用所有的白边,不断的加边,看最多能使用多少条白边使得不形成环,求得白边使用的数量的上界
    然后是否存在斐波那契数载这个区间

    我们等于是要证明对于所有在min和max之间的白边数我们都能够达到。

    考虑从最小的min开始,我总可以找到一条黑边,使得将它去掉在补上一条白边保持图联通。为什么呢,如果在某一个状态(设白边数为x)下,不存在一条黑边可以被白边代替,那么现在我们把所有黑边去掉,剩下x条白边,那我们知道,x一定等于max,因为若x<max,那么我们在算max的那个步骤中,先将这x条白边加入,还可以在加入max-x条白边使得不存在环,那么这与没有一条黑边可以被白边代替矛盾,所以这就证明了从min到max我都可以达到

     
      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 using namespace std;
      5 struct node
      6 {
      7     int u,v,c;
      8 } N[100005];
      9 int fib[50];
     10 int fa[100005];
     11 int t;
     12 int n,m;
     13 int coun;
     14 int find(int root)
     15 {
     16     if(root==fa[root])
     17         return root;
     18     else
     19         return fa[root]=find(fa[root]);
     20 }
     21 void unin(int a,int b)
     22 {
     23     int aa=find(a);
     24     int bb=find(b);
     25     if(aa!=bb)
     26         fa[aa]=bb;
     27 }
     28 void init()
     29 {
     30     for(int i=1; i<=n; i++)
     31         fa[i]=i;
     32 }
     33 void fi()
     34 {
     35     fib[1]=1;
     36     fib[2]=2;
     37     for(int i=3;; i++)
     38     {
     39         fib[i]=fib[i-1]+fib[i-2];
     40         if(fib[i]>100005)
     41         {
     42             coun=i;
     43             break;
     44         }
     45     }
     46 }
     47 int kruscal(int exm)
     48 {
     49     init();
     50     int k=0;
     51     for(int i=1; i<=m; i++)
     52     {
     53         if(N[i].c!=exm)
     54         {
     55             if(find(N[i].u)!=find(N[i].v))
     56             {
     57                 k++;
     58                 unin(N[i].u,N[i].v);
     59             }
     60         }
     61     }
     62     return k;
     63 }
     64 int main()
     65 {
     66     fi();
     67     while(scanf("%d",&t)!=EOF)
     68     {
     69         for(int j=1; j<=t; j++)
     70         {
     71             scanf("%d %d",&n,&m);
     72             for(int i=1; i<=m; i++)
     73             scanf("%d %d %d",&N[i].u,&N[i].v,&N[i].c);
     74             printf("Case #%d: ",j);
     75             int zha;
     76             zha=kruscal(2);//可以使用白边和黑边
     77             if(zha!=(n-1))//判环
     78             {
     79                 printf("No
    ");
     80                 continue;
     81             }
     82             int l=n-1-kruscal(1);//构成生成树的白边数量的下限
     83             int r=kruscal(0);// 构成生成树的白边数量的上限
     84             int flag=0;
     85             for(int i=1; i<coun; i++)//判断是否存在满足条件的fib
     86             {
     87                 if(fib[i]>=l&&fib[i]<=r)
     88                 {
     89                     printf("Yes
    ");
     90                     flag=1;
     91                     break;
     92 
     93                 }
     94             }
     95             if(flag==0)
     96                 printf("No
    ");
     97         }
     98     }
     99     return 0;
    100 }
  • 相关阅读:
    kis 7.5和360似乎存在兼容性的问题,
    mysql timeout
    update users set a=1 where id in (1,2,3)这句在rails中该如何写呢
    mysql数据库 text类型的长度限制,使用change_column来进行长度的修改并不影响原有数据
    杭州的一个托管idc商
    User.find_each
    ruby 批量更新
    mongodb kt双机房灾备
    imagemagick使用
    kingdee kis
  • 原文地址:https://www.cnblogs.com/hsd-/p/5703032.html
Copyright © 2011-2022 走看看