【HDU 4786 Fibonacci Tree】最小生成树

简介: 一个由n个顶点m条边(可能有重边)构成的无向图(可能不连通),每条边的权值不是0就是1。 给出n、m和每条边的权值,问是否存在生成树,其边权值和为fibonacci数集合{1,2,3,5,8...}中的一个。

一个由n个顶点m条边(可能有重边)构成的无向图(可能不连通),每条边的权值不是0就是1。

给出n、m和每条边的权值,问是否存在生成树,其边权值和为fibonacci数集合{1,2,3,5,8...}中的一个。

求最小生成树和最大生成树,得到生成树边权和的下界left和上界right。这道题由于每条边权值不是0就是1,因此生成树边权和可以覆盖到[left,right]的每一个数。那么求得[left,right],看是否有fibonacci数在区间内就可以了。

  1 #include <cstdio>
  2 #include <algorithm>
  3 using namespace std;
  4 const int MAX_N=100005;
  5 const int MAX_M=100005;
  6 int T;
  7 int n,m;
  8 struct Edge
  9 {
 10     int from,to,cost;
 11 }edges[MAX_M];
 12 
 13 bool cmp0(const Edge e1,const Edge e2)
 14 {return e1.cost<e2.cost;}
 15 bool cmp1(const Edge e1,const Edge e2)
 16 {return e1.cost>e2.cost;}
 17 
 18 int parent[MAX_N];
 19 int rankk[MAX_N];
 20 void init(int N)
 21 {
 22     for(int i=0;i<=N;i++)
 23     {
 24         parent[i]=i;
 25         rankk[i]=0;
 26     }
 27 }
 28 int find(int x)
 29 {
 30     if(parent[x]==x) return x;
 31     return parent[x]=find(parent[x]);
 32 }
 33 void unite(int x,int y)
 34 {
 35     x=find(x);
 36     y=find(y);
 37     if(x==y) return;
 38     if(rankk[x]<rankk[y]) parent[x]=y;
 39     else
 40     {
 41         parent[y]=x;
 42         if(rankk[x]==rankk[y]) rankk[x]++;
 43     }
 44 }
 45 bool same(int x,int y)
 46 {return find(x)==find(y);}
 47 
 48 int kruscal()
 49 {
 50     int ans=0;
 51     init(n);
 52     for(int i=0;i<m;i++)
 53     {
 54         if(!same(edges[i].from,edges[i].to))
 55         {
 56             unite(edges[i].from,edges[i].to);
 57             ans+=edges[i].cost;
 58         }
 59     }
 60     return ans;
 61 }
 62 
 63 int fib[25];
 64 void init_fib()
 65 {
 66     fib[0]=fib[1]=1;
 67     for(int i=2;fib[i-1]<MAX_M;i++)
 68         fib[i]=fib[i-1]+fib[i-2];
 69 /*
 70     for(int i=0;fib[i]<MAX_M;i++)
 71         printf("%d %d\n",i,fib[i]);
 72     printf("\n");
 73 */
 74 }
 75 
 76 int main()
 77 {
 78     init_fib();
 79     freopen("4786.txt","r",stdin);
 80     scanf("%d",&T);
 81     for(int ca=1;ca<=T;ca++)
 82     {
 83         scanf("%d%d",&n,&m);
 84         for(int i=0;i<m;i++)
 85             scanf("%d%d%d",&edges[i].from,&edges[i].to,&edges[i].cost);
 86         printf("Case #%d: ",ca);
 87         if(n==1||m==0||m<n-1)//所给边数<n-1一定不连通
 88         {
 89             printf("No\n");
 90             continue;
 91         }
 92         sort(edges,edges+m,cmp0);
 93         int left=kruscal();
 94         sort(edges,edges+m,cmp1);
 95         int right=kruscal();
 96 
 97         int flag=1;
 98         for(int i=2;i<=n;i++)//判是否为连通图(重边不影响求MST,但不能仅凭所给边数m判是否连通)
 99             if(!same(1,i)){flag=0; break;}
100         if(!flag)
101             {printf("No\n"); continue;}
102 
103         flag=0;
104         for(int i=0;i<25;i++)//枚举100000以内的fibonacci数,有进入范围的即可
105             if(left<=fib[i]&&fib[i]<=right)
106                 {flag=1;break;}
107         if(flag) printf("Yes\n");
108         else printf("No\n");
109     }
110     return 0;
111 }

开始觉得可以按一种贪心策略求得一个最优解,如果命中不了fibonacci数则无解。

想贪心的先选权值为0的边,画图发现可能错过fibonacci数,贪心的先选权值为1的边依然可能错过。

画各种例子,发现割边是必须取的,因此边权和有个下界。去掉割边后剩下的就是圈了,每个圈去掉一条边即得生成树;想枚举每个圈的所有情况看能不能命中fibonacci数,但并是不会实现,尤其对很复杂的图。

队友提出过求出上下界然后看是否有fibonacci数在之间,无奈我开始没听懂。。。

另,用m>=n-1判连通的话,m是去掉重边后的边数,WA在这里实在是。。。唉

目录
相关文章
|
3月前
|
存储 缓存 API
信息检索重排序技术深度解析:Cross-Encoders、ColBERT与大语言模型方法的实践对比
本文将深入分析三种主流的重排序技术:Cross-Encoders(交叉编码器)、ColBERT以及基于大语言模型的重排序器,并详细阐述各方案在实际应用中的性能表现、成本考量以及适用场景。
214 3
信息检索重排序技术深度解析:Cross-Encoders、ColBERT与大语言模型方法的实践对比
|
4月前
|
人工智能 自然语言处理 JavaScript
【开源项目】MaxKB4J基于java开发的工作流和 RAG智能体的知识库问答系统
MaxKB4J是一款基于Java开发的开源LLM工作流应用与RAG知识库问答系统,结合MaxKB和FastGPT优势,支持智能客服、企业知识库等场景。它开箱即用,可直接上传/爬取文档,支持多种大模型(如Qwen、通义千问等),具备灵活的工作流编排能力,并无缝嵌入第三方系统。技术栈包括Vue.js、Springboot3、PostgreSQL等,提供稳定高效的智能问答解决方案。访问地址:`http://localhost:8080/ui/login`,项目详情见[Gitee](https://gitee.com/taisan/MaxKB4j)。
|
开发框架 前端开发 应用服务中间件
部署基于.netcore5.0的ABP框架后台Api服务端,以及使用Nginx部署Vue+Element前端应用
部署基于.netcore5.0的ABP框架后台Api服务端,以及使用Nginx部署Vue+Element前端应用
|
11月前
|
监控 API 数据安全/隐私保护
小红书详情API接口的获取与应用
在互联网信息爆炸的时代,小红书凭借丰富的用户生成内容(UGC)和精准的推荐系统迅速崛起,成为重要的社区电商平台。为了帮助开发者高效利用平台数据,小红书开放平台提供了多种API接口,涵盖商品详情和笔记详情等。本文详细介绍了如何注册、申请权限、构建请求、处理响应及应用这些API接口,旨在为开发者提供全面的指南,助力数据驱动的决策与创新。
4471 1
|
JavaScript Java 测试技术
基于springboot+vue.js的在线教育系统附带文章和源代码设计说明文档ppt
基于springboot+vue.js的在线教育系统附带文章和源代码设计说明文档ppt
150 9
基于springboot+vue.js的在线教育系统附带文章和源代码设计说明文档ppt
|
敏捷开发 SQL 前端开发
PRD的编写要点详解
PRD的编写要点详解
679 0
|
人工智能 区块链 语音技术
AAAI 2023|基于多模态标签聚合的视频检索模型TABLE,多项SOTA(1)
AAAI 2023|基于多模态标签聚合的视频检索模型TABLE,多项SOTA
417 0
|
机器学习/深度学习 算法 搜索推荐
【玩转数据系列十三】机器学习算法基于信用卡消费记录做信用评分
机器学习算法基于信用卡消费记录做信用评分 背景 如果你是做互联网金融的,那么一定听说过评分卡。评分卡是信用风险评估领域常用的建模方法,评分卡并不简单对应于某一种机器学习算法,而是一种通用的建模框架,将原始数据通过分箱后进行特征工程变换,继而应用于线性模型进行建模的一种方法。
15290 1
|
NoSQL Java 网络性能优化
MongoDB · 特性分析 · 网络性能优化
从 C10K 说起 对于高性能即时通讯技术(或者说互联网编程)比较关注的开发者,对C10K问题(即单机1万个并发连接问题)应该都有所了解。『C10K』概念最早由 Dan Kegel 发布于其个人站点,即出自其经典的《The C10K problem》一文[1]。 于是FreeBSD推出了kqueue,Linux推出了epoll,Windows推出了IOCP。这些操作系统提供的功能就是为了解决C1
4500 0