HDU 4786

来源:互联网 发布:石家庄seo博客 编辑:程序博客网 时间:2024/06/07 06:40

智商捉急。看了题解

先判断图是否联通,然后优先选黑边。看白边最小选多少,再优先选白边,看白边最多选多少。于是从最小到最大都可以构成这样的生成树了。

可以想象一下,既然已经可以联通成生成树了,那么黑边先选,再最小选出白边,一定存在许多白边可以替代黑边,多选一条白边,就一定找的出相应联通关系的黑边,一直到白边最多。

#include<cstdio>#include<cstring>#include<algorithm>#define maxl 100010using namespace std;int n,m,cas;int f[maxl],fib[maxl];struct ed{int x,y,w;} e[maxl];bool yes;bool cmp1(const ed &x,const ed &y){return x.w<y.w;}bool cmp2(const ed &x,const ed &y){return x.w>y.w;}void prework(){scanf("%d%d",&n,&m);for(int i=1;i<=m;i++)scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].w);}int find(int x){if(f[x]!=x)f[x]=find(f[x]);return f[x];}int kru(){int cnt=0,x,y,sum=0;for(int i=1;i<=n;i++)f[i]=i;for(int i=1;i<=m;i++){x=find(e[i].x);y=find(e[i].y);if(x!=y){sum++;f[y]=x;cnt+=e[i].w;if(sum==n-1)break;}}if(sum<n-1)return -1;return cnt;}void mainwork(){int l,r;yes=false;sort(e+1,e+1+m,cmp1);l=kru();if(l==-1) return;sort(e+1,e+1+m,cmp2);r=kru();fib[1]=1;for(int i=2;i<=26;i++){fib[i]=fib[i-1]+fib[i-2];if(fib[i]>=l && fib[i]<=r)yes=true;}}void print(){if(yes)printf("Case #%d: Yes\n",cas);elseprintf("Case #%d: No\n",cas);}int main(){int t;scanf("%d",&t);for(cas=1;cas<=t;cas++){prework();mainwork();print();}return 0;}


原创粉丝点击