hdu4786

来源:互联网 发布:开博尔网络机顶盒价格 编辑:程序博客网 时间:2024/06/10 18:01

链接:点击打开链接

题意:给出一些权值为0或1的边,问是否能

代码:

#include <queue>#include <vector>#include <math.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;int V,E,tmp;int fib[50];int par[100005],ran[100005],vis[100005];void init(int n){    int i;    for(i=0;i<=n;i++){        ran[i]=0;        par[i]=i;    }}int find(int x){    if(par[x]==x)    return x;    return par[x]=find(par[x]);}void unite(int x,int y){    x=find(x);    y=find(y);    if(x==y)    return;    if(ran[x]<ran[y])    par[x]=y;    else{        par[y]=x;        if(ran[x]==ran[y])        ran[x]++;    }}bool same(int x,int y){    return find(x)==find(y);}struct node{    int u,v,cost;};bool cmp1(node a,node b){    return a.cost<b.cost;}bool cmp2(node a,node b){    return a.cost>b.cost;}node es[100005];int kruskal(){    int i,res=0;    init(V);    for(i=0;i<E;i++){        node e=es[i];        if(!same(e.u,e.v)){            unite(e.u,e.v);            res+=e.cost;            tmp++;        }    }    return res;}int main(){                                     //其实就是在最小生成树和最大生成树中间的值    int t,i,cas,minn,maxx;                      //中判断是否有斐波那契数    fib[0]=1,fib[1]=2;                          //最小生成树一定是你含1最少的生成树,因此类    for(i=2;i<=24;i++)                          //似与次小生成树,每次找一个不在最小生成树上    fib[i]=fib[i-1]+fib[i-2];                   //的长度为1的边添加进去,则一定会形成一个环,    scanf("%d",&t);                             //去掉这个环上的一条长度是0的边则一定会形成一    for(cas=1;cas<=t;cas++){                    //个更大的生成树,不断执行当前操作,直到生成树    tmp=0;                                      //的值不变,也就是变成了1最多的生成树,也就是最大    scanf("%d%d",&V,&E);                        //生成树    memset(vis,0,sizeof(vis));    for(i=0;i<E;i++)    scanf("%d%d%d",&es[i].u,&es[i].v,&es[i].cost);    sort(es,es+E,cmp1);    minn=kruskal();                             //最小生成树    if(tmp!=V-1){                               //需要判断是否能生成树,在kruskal里判断连了几条就行            printf("Case #%d: No\n",cas);        continue;    }    sort(es,es+E,cmp2);    maxx=kruskal();                             //最大生成树    for(i=minn;i<=maxx;i++)    if((*lower_bound(fib,fib+25,i))!=(*upper_bound(fib,fib+25,i))){        printf("Case #%d: Yes\n",cas);          //判断是否存在斐波那契        goto next;    }    printf("Case #%d: No\n",cas);    next:;    }    return 0;}


0 0
原创粉丝点击