HDU 4786 生成树 并查集+极大极小值 黑白边 确定选择白边的数量
题意:
给定一个无向图
n 个点 m条无向边
u v val
val == 1 表示边(u, v) 为白边
问能否找到n个点的生成树, 使得白边数为斐波那契数
思路:
并查集求图是否连通( 是否存在生成树)
求出 最多白边树 的 白边数量
求出 最少白边树 的 白边数量
若[最少, 最多] 区间内存在斐波那契数 ,则满足条件
(也就是说,白边的数量是连续有解的)
//YY得证
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string>
#include<queue>
#include<string.h>
#include<map>
#include<set>
#include<stack>
#include<vector>
#include<math.h>
#include<algorithm>
#define N 101010
#define inf 10000000
using namespace std;
inline int Min(int a,int b){return a>b?b:a;}
inline int Max(int a,int b){return a<b?b:a;}int f[N];
int find(int x){return x==f[x]?x:(f[x] = find(f[x]));}
void Union(int u, int v){int fu = find(u), fv = find(v);if(fu>fv)f[fu] = fv;else f[fv] = fu;
}
set<int>fib;
int n, m;
struct node{int u,v,c;
}edge[N];
int edgenum;
bool cmp1(node a,node b){return a.c<b.c;}
bool cmp2(node a,node b){return a.c>b.c;}
int main(){int T, Cas = 1;scanf("%d",&T);int i, j, col;fib.clear();fib.insert(1);fib.insert(2);j=1;for(i=2;i<=N;){fib.insert(i+j);int lala = i;i = i+j;j = lala;}while(T--){scanf("%d %d", &n, &m);for(i=1;i<=n;i++)f[i] = i;edgenum = 0;while(m--){int u,v;scanf("%d %d %d",&u,&v,&col);edge[edgenum].u = u;edge[edgenum].v = v;edge[edgenum++].c = col;int fx = find(u), fy = find(v);if(fx == fy)continue;Union(fx,fy);}printf("Case #%d: ",Cas++);for(i=1;i<=n;i++)find(i);bool su = true;for(i=1;i<=n;i++)if(f[i]!=f[1]){su = false; break;}if(su == false){printf("No\n");continue;}for(i=1;i<=n;i++)f[i] = i;sort(edge, edge+edgenum, cmp1);int size = 0, bl=0, bm=0;for(i=0;i<edgenum;i++){int u =edge[i].u, v=edge[i].v;int fu = find(u), fv=find(v);if(fu == fv)continue;size++;bl+= edge[i].c;Union(fu, fv);if(size==n-1)break;}for(i=1;i<=n;i++)f[i] = i;sort(edge, edge+edgenum, cmp2);size = 0;for(i=0;i<edgenum;i++){int u =edge[i].u, v=edge[i].v;int fu = find(u), fv=find(v);if(fu == fv)continue;size++;bm+= edge[i].c;Union(fu, fv);if(size==n-1)break;}if(fib.upper_bound(bl) == fib.end() ){printf("No\n");continue;}if((*fib.lower_bound(bl) )>bm){printf("No\n");continue;}printf("Yes\n");}return 0;
}
/*
4 2
1 2 1
3 4 1*/
转载于:https://www.cnblogs.com/riasky/p/3431089.html
HDU 4786 生成树 并查集+极大极小值 黑白边 确定选择白边的数量相关推荐
- hdu 1232 经典并查集应用
http://acm.hdu.edu.cn/showproblem.php?pid=1232 完全就是并查集的应用啊... View Code 1 #include<iostream> 2 ...
- 畅通工程 hdu 1232 HDU - 1863 (并查集+最小生成树)
畅通工程hdu 1232 并查集 Problem Description Input Output 参考代码 HDU - 1863 Problem Description Input Output 参 ...
- HDU 3234 Exclusive-OR [并查集]
http://acm.hdu.edu.cn/showproblem.php?pid=3234 #Description 给你N个数,X0-X(N-1) 执行Q个查询 三种格式 I p v Xp= v ...
- HDU 3234 Exclusive-OR(并查集)
转载请注明出处,谢谢http://blog.csdn.net/acm_cxlove/article/details/7854526 by---cxlove 题目:给出N个数,给出一些条件, ...
- HDU 5606 tree 并查集
tree 把每条边权是1的边断开,发现每个点离他最近的点个数就是他所在的连通块大小. 开一个并查集,每次读到边权是0的边就合并.最后Ansi=size[findset(i)],size表示每个并 ...
- hdu 1116 欧拉回路 并查集 一组字符串能否首尾相连成一个字符串
主要是欧拉回路的基础知识,用并查集加工处理 注意欧拉回路和并查集的细节判断 不能粘贴复制,一定要理解之后再敲一遍代码,否则浪费更多的时间 #include <stdio.h> #inclu ...
- hdu 3038(种类并查集)
题目大意:有n次询问,给出a到b区间的总和,问这n次给出的总和中有几次是和前面已近给出的是矛盾的 解题思路:这道题第一次接触很难往并查集方向去思考.这里使用的并查集很灵活,不仅仅要记录其父亲节点,同时 ...
- hdu 3635(并查集+路径压缩变形)
解题思路:这道题想了我好久,因为我把城市的编号一起考虑进去了,结果想了好久都没A,最后看了别人的题解居然都没有考虑到城市的编号,不考虑城市编号的问题的话就是一个很水的并查集了. #include< ...
- 27行代码AC_How Many Tables HDU - 1213(并查集讲解)
励志用少的代码做高效表达 分析与思路 n个人吃饭,只能熟人和熟人坐在一起,否则就一个人坐一桌. 给定m个关系(m对熟人),问最少需要多少张桌子. 纯粹考查的并查集模板的题, 给定m个关系就代表了m个集 ...
最新文章
- leetcode算法题--Decode String
- 谷歌开源下一代推荐系统模拟器:RecSim NG
- linux yum install和yum localinstall、rpm -ivh的区别
- 控制台当前行显示进度条,不换行
- 深度学习数据集制作工作_创建我的第一个深度学习+数据科学工作站
- mysql不同字段full join_Mysql实现full join的替换方法
- 去除面部黑色素小妙招_面部黑色素沉着怎么去除 推荐几个去黑色素的方法
- MyEclipse 10, 2013, 2014 破解、注册码
- Java算法之移除元素
- java中static代码块_static怎样在java中修改代码块?
- Atitit.故障排除系列---NoClassDefFoundError NoClassDefFoundError ClassNotFoundException
- Set集合之HashSet添加的数据是如何保证不重复的
- 土豆聊天poeato Chat注册账号时提示网络刺错误怎么解决
- 云桌面优缺点_云桌面中VDI架构有什么优势和劣势?
- 将QQ语音的slk格式转化为wma
- 《opencv学习》Shi-Tomasi 角点检测
- 疫情地图网页版代码实例
- 数据结构之单源最短路径(迪杰斯特拉算法)-(九)
- 计算机的数学思想源头(回复“计算机数学”可下载PDF典藏版)
- git 分支教程小游戏