标签:
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
Case #1: Yes Case #2: No
2013 Asia Chengdu Regional Contest
有n个点,m条边,有黑白之分,问连通所有点时的边中,白边的个数能不能是斐波那契数列中的一个数
思路:先用白边连图,求出白边的个数,再先用黑边连图,求出白边另个值,,这两个值就是白边个数的取值范围
2015,7,30
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define M 100000+10 struct node{ int s,e,val; }sd[M]; int x[M]; int a[55]; bool cmp1(node a,node b){ return a.val>b.val; } bool cmp2(node a,node b){ return a.val<b.val; } void init() { for(int i=0;i<M;i++) x[i]=i; } int find(int k) { if(x[k]==k) return k; x[k]=find(x[k]); return x[k]; } int main() { int t,m,n,v=1,i; int num,start,end; a[1]=1; a[2]=2; for(i=3;i<55;i++)//因为边最多有100000条,所以斐波那契数大于这个数时就可以了,55足够了 a[i]=a[i-1]+a[i-2]; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); for(i=0;i<m;i++) scanf("%d%d%d",&sd[i].s,&sd[i].e,&sd[i].val); sort(sd,sd+m,cmp2); num=0; init(); for(i=0;i<m;i++){ int fa=find(sd[i].s); int fb=find(sd[i].e); if(fa!=fb){ x[fa]=fb; if(sd[i].val==1) num++; } } start=num; sort(sd,sd+m,cmp1); num=0; init(); for(i=0;i<m;i++){ int fa=find(sd[i].s); int fb=find(sd[i].e); if(fa!=fb){ x[fa]=fb; if(sd[i].val==1) num++; } } end=num; int ok=0; for(i=1;i<=n;i++){ if(find(i)!=find(1)){ ok=1; break; } } printf("Case #%d: ",v++); if(ok) printf("No\n");//如果没有连通所有点直接输出No else{ for(i=1;i<50;i++){//注意这个i要从1开始,因为输入1个点0条边时要输出No,,我找了半天错= =+ if(a[i]>= start && a[i]<=end){ ok=1; break; } } if(ok) printf("Yes\n"); else printf("No\n"); } } return 0; }
hdu 4786 Fibonacci Tree(最小生成树)
标签:
原文地址:http://blog.csdn.net/ling_du/article/details/47150135