zoukankan      html  css  js  c++  java
  • hdu4786 Fibonacci Tree[最小生成树]【结论题】

    一道结论题:如果最小生成树和最大生成树之间存在fib数,成立。不存在或者不连通则不成立。由于是01图,所以这个区间内的任何生成树都存在

    证明:数学归纳?如果一棵树没有办法再用非树边0边替代1边了,那他就是最小生成树。如果一棵生成树大于最小生成树,那么他显然存在可以被替换的1边,否则会与最小矛盾。最大生成树存在(与最小生成树相等时显然结论成立),那么他一定可以有可以替换的边,所以所有区间内的生成树都存在。

    吐槽:我一开始以为要依据fib的性质合并块。。研究好久。。冏。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<queue>
     7 #define dbg(x) cerr << #x << " = " << x <<endl
     8 #define dbg2(x,y) cerr<< #x <<" = "<< x <<"  "<< #y <<" = "<< y <<endl
     9 using namespace std;
    10 typedef long long ll;
    11 typedef double db;
    12 typedef pair<int,int> pii;
    13 template<typename T>inline T _min(T A,T B){return A<B?A:B;}
    14 template<typename T>inline T _max(T A,T B){return A>B?A:B;}
    15 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;}
    16 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;}
    17 template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
    18 template<typename T>inline T read(T&x){
    19     x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1;
    20     while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x;
    21 }
    22 const int N=1e5+7;
    23 struct thxorz{int u,v,w;}e[N];
    24 struct stothx{int nxt,to;}G[N<<1];
    25 int Head[N],tot;
    26 inline void Addedge(int x,int y){
    27     G[++tot].to=y,G[tot].nxt=Head[x],Head[x]=tot;
    28     G[++tot].to=x,G[tot].nxt=Head[y],Head[y]=tot;
    29 }
    30 int vis[N];
    31 void dfs(int x){
    32     vis[x]=1;
    33     for(register int j=Head[x];j;j=G[j].nxt)if(!vis[G[j].to])dfs(G[j].to);
    34 }
    35 int T,n,m,minst,maxst,flag;
    36 struct dsu{
    37     int anc[N];
    38     inline void Clear(){for(register int i=1;i<=n;++i)anc[i]=i;}
    39     inline int Find(int x){return anc[x]==x?x:anc[x]=Find(anc[x]);}
    40 }S;
    41 int fib[]={1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368,75025};//24
    42 
    43 int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
    44     read(T);for(register int testcase=1;testcase<=T;++testcase){
    45         read(n),read(m);minst=maxst=flag=0;
    46         memset(Head,0,sizeof Head);tot=0;
    47         for(register int i=1;i<=m;++i)read(e[i].u),read(e[i].v),read(e[i].w),Addedge(e[i].u,e[i].v);
    48         memset(vis,0,sizeof vis);dfs(1);
    49         for(register int i=1;i<=n;++i)if(!vis[i]){flag=1;break;}
    50         if(flag){printf("Case #%d: No
    ",testcase);continue;}
    51         S.Clear();
    52         for(register int i=1;i<=m;++i)if(!e[i].w)if(S.Find(e[i].u)^S.Find(e[i].v))
    53             S.anc[S.anc[e[i].u]]=S.anc[e[i].v];
    54         for(register int i=1;i<=m;++i)if(e[i].w)if(S.Find(e[i].u)^S.Find(e[i].v))
    55             S.anc[S.anc[e[i].u]]=S.anc[e[i].v],++minst;
    56         S.Clear();
    57         for(register int i=1;i<=m;++i)if(e[i].w)if(S.Find(e[i].u)^S.Find(e[i].v))
    58             S.anc[S.anc[e[i].u]]=S.anc[e[i].v],++maxst;
    59         for(register int i=1;i<=m;++i)if(!e[i].w)if(S.Find(e[i].u)^S.Find(e[i].v))
    60             S.anc[S.anc[e[i].u]]=S.anc[e[i].v];
    61         int x=lower_bound(fib+1,fib+24,minst)-fib;
    62         if(maxst>=fib[x])printf("Case #%d: Yes
    ",testcase);
    63         else printf("Case #%d: No
    ",testcase);
    64     }
    65     return 0;
    66 }
    View Code

    总结:做生成树问题没有什么其他方法,所以还是最好多往MST上去想。。

  • 相关阅读:
    s3c2440 移值u-boot-2016.03 第6篇 支持mtd yaffs 烧写
    s3c2440 移值u-boot-2016.03 第5篇 支持dm9000 识别
    s3c2440 移值u-boot-2016.03 第4篇 支持NAND flash 识别
    [转]MySQL数据库引擎
    [转]史上最全的MSSQL复习笔记
    [转]解析json:与array,list,map,bean,xml相互转化
    [转]Web程序员必须知道的 Console 对象里的九个方法
    大数据Spark超经典视频链接全集
    王家林 大数据Spark超经典视频链接全集[转]
    [转]WEB开发者必备的7个JavaScript函数
  • 原文地址:https://www.cnblogs.com/saigyouji-yuyuko/p/11693662.html
Copyright © 2011-2022 走看看