【HDU 4786 Fibonacci Tree】最小生成树
一个由n个顶点m条边(可能有重边)构成的无向图(可能不连通),每条边的权值不是0就是1。
给出n、m和每条边的权值,问是否存在生成树,其边权值和为fibonacci数集合{1,2,3,5,8...}中的一个。
求最小生成树和最大生成树,得到生成树边权和的下界left和上界right。这道题由于每条边权值不是0就是1,因此生成树边权和可以覆盖到[left,right]的每一个数。那么求得[left,right],看是否有fibonacci数在区间内就可以了。
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAX_N=;
const int MAX_M=;
int T;
int n,m;
struct Edge
{
int from,to,cost;
}edges[MAX_M]; bool cmp0(const Edge e1,const Edge e2)
{return e1.cost<e2.cost;}
bool cmp1(const Edge e1,const Edge e2)
{return e1.cost>e2.cost;} int parent[MAX_N];
int rankk[MAX_N];
void init(int N)
{
for(int i=;i<=N;i++)
{
parent[i]=i;
rankk[i]=;
}
}
int find(int x)
{
if(parent[x]==x) return x;
return parent[x]=find(parent[x]);
}
void unite(int x,int y)
{
x=find(x);
y=find(y);
if(x==y) return;
if(rankk[x]<rankk[y]) parent[x]=y;
else
{
parent[y]=x;
if(rankk[x]==rankk[y]) rankk[x]++;
}
}
bool same(int x,int y)
{return find(x)==find(y);} int kruscal()
{
int ans=;
init(n);
for(int i=;i<m;i++)
{
if(!same(edges[i].from,edges[i].to))
{
unite(edges[i].from,edges[i].to);
ans+=edges[i].cost;
}
}
return ans;
} int fib[];
void init_fib()
{
fib[]=fib[]=;
for(int i=;fib[i-]<MAX_M;i++)
fib[i]=fib[i-]+fib[i-];
/*
for(int i=0;fib[i]<MAX_M;i++)
printf("%d %d\n",i,fib[i]);
printf("\n");
*/
} int main()
{
init_fib();
freopen("4786.txt","r",stdin);
scanf("%d",&T);
for(int ca=;ca<=T;ca++)
{
scanf("%d%d",&n,&m);
for(int i=;i<m;i++)
scanf("%d%d%d",&edges[i].from,&edges[i].to,&edges[i].cost);
printf("Case #%d: ",ca);
if(n==||m==||m<n-)//所给边数<n-1一定不连通
{
printf("No\n");
continue;
}
sort(edges,edges+m,cmp0);
int left=kruscal();
sort(edges,edges+m,cmp1);
int right=kruscal(); int flag=;
for(int i=;i<=n;i++)//判是否为连通图(重边不影响求MST,但不能仅凭所给边数m判是否连通)
if(!same(,i)){flag=; break;}
if(!flag)
{printf("No\n"); continue;} flag=;
for(int i=;i<;i++)//枚举100000以内的fibonacci数,有进入范围的即可
if(left<=fib[i]&&fib[i]<=right)
{flag=;break;}
if(flag) printf("Yes\n");
else printf("No\n");
}
return ;
}
开始觉得可以按一种贪心策略求得一个最优解,如果命中不了fibonacci数则无解。
想贪心的先选权值为0的边,画图发现可能错过fibonacci数,贪心的先选权值为1的边依然可能错过。
画各种例子,发现割边是必须取的,因此边权和有个下界。去掉割边后剩下的就是圈了,每个圈去掉一条边即得生成树;想枚举每个圈的所有情况看能不能命中fibonacci数,但并是不会实现,尤其对很复杂的图。
队友提出过求出上下界然后看是否有fibonacci数在之间,无奈我开始没听懂。。。
另,用m>=n-1判连通的话,m是去掉重边后的边数,WA在这里实在是。。。唉
【HDU 4786 Fibonacci Tree】最小生成树的更多相关文章
- HDU 4786 Fibonacci Tree 最小生成树
Fibonacci Tree 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=4786 Description Coach Pang is intere ...
- hdu 4786 Fibonacci Tree (2013ACMICPC 成都站 F)
http://acm.hdu.edu.cn/showproblem.php?pid=4786 Fibonacci Tree Time Limit: 4000/2000 MS (Java/Others) ...
- HDU 4786 Fibonacci Tree(生成树,YY乱搞)
http://acm.hdu.edu.cn/showproblem.php? pid=4786 Fibonacci Tree Time Limit: 4000/2000 MS (Java/Others ...
- hdu 4786 Fibonacci Tree(最小生成树)
Fibonacci Tree Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
- HDU 4786 Fibonacci Tree (2013成都1006题)
Fibonacci Tree Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- HDU 4786 Fibonacci Tree
Fibonacci Tree Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) P ...
- HDU 4786 Fibonacci Tree (2013成都1006题) 最小生成树+斐波那契
题意:问生成树里能不能有符合菲波那切数的白边数量 思路:白边 黑边各优先排序求最小生成树,并统计白边在两种情况下数目,最后判断这个区间就可以.注意最初不连通就不行. #include <stdi ...
- hdu 4786 Fibonacci Tree 乱搞 智商题目 最小生成树
首先计算图的联通情况,如果图本身不联通一定不会出现生成树,输出"NO",之后清空,加白边,看最多能加多少条,清空,加黑边,看能加多少条,即可得白边的最大值与最小值,之后判断Fibo ...
- HDU 4786 Fibonacci Tree 生成树
链接:http://acm.hdu.edu.cn/showproblem.php?pid=4786 题意:有N个节点(1 <= N <= 10^5),M条边(0 <= M <= ...
随机推荐
- Linux系统编程(8)—— 进程之进程控制函数fork
fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事. 一个进程调用fork()函数后,系统先 ...
- MFC DestroyWindow窗口对象和窗口句柄的销毁
考虑单窗口情况: 假设自己通过new创建了一个窗口对象pWnd,然后pWnd->Create.则销毁窗口的调用次序: 1. 手工调用pWnd->DestroyWindow(): 2. De ...
- Dos命令---ipconfig
Dos命令---ipconfig 作者:vpoet mail:vpoet_sir@163.com ipconfig是很常用的Dos命令,我们可以用ipconfig /?查看该命令的说明.在linux下 ...
- mongoDb c driver
1,yum dependencies Centos,RHEL Fedora: $ sudo yum install git gcc automake autoconf libtool Debian: ...
- Windows7&IIS7.5部署Discuz
IIS CGI一定要安装 IIS 网站中添加关联程序 ,添加默认文档 http://www.cnblogs.com/ajunForNet/archive/2012/09/12/2682063.html
- [Manacher][HDU3613][Best Reward]
题意: 将一段字符串 分割成两个串 如果分割后的串为回文串,则该串的价值为所有字符的权值之和(字符的权值可能为负数),否则为0. 问如何分割,使得两个串权值之和最大 思路: 裸的: 枚举分割点,计算, ...
- .Net 中DataSet导出为excel的方法
依旧是留下代码防止以后忘记 protected void Export_Click(object sender, EventArgs e) { DataSet data = "" ...
- RDLC报表系列(一) 简单的动态数据绑定和配置
RDLC系列链接 RDLC报表系列(一) 简单的动态数据绑定和配置 RDLC报表系列(二) 行分组 RDLC报表系列(三) 总计和折叠 RDLC报表系列(四) 矩阵 RDLC报表系列(五) 简单的图 ...
- 安卓开发之非常好用的AndroidOne框架DownloadManager
AndroidOne框架是采用MVC模式,集成了Android主流开源技术及组件,是一款极速且简单高效开发框架,整个项目包含两个部分AndroidOne,oneCore AndroidOne为演示项目 ...
- 将已有项目导入Gitlab
登陆GitLab,创建添加项目. 写入项目的基本信息,包括名称.描述.权限等等. cd existing_folder git init git remote add origin git@10.10 ...