两个BUG鸣翠柳,一行代码上西天。。。

hdu4786 Fibonacci Tree(生成树)问能否用白边和黑边构成一棵生成树,并且白边数量是斐波那契数。

题解:分别优先加入白边和黑边,求出生成树能包含白边的最大值和最小值,其间有值为斐波那契数即可。

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. using namespace std;
  5. const int M=1e5+;
  6. const int N=1e5+;
  7. struct edge{
  8. int u,v,w;
  9. }e[M];
  10. int f[N];
  11. int fi[];
  12. int n,m,ans;
  13. int cmp(edge a,edge b){
  14. return a.w<b.w;
  15. }
  16. void init(){
  17. for(int i=;i<=n;++i) f[i]=i;
  18. }
  19. int fin(int x){
  20. if(x!=f[x])f[x]=fin(f[x]);
  21. return f[x];
  22. }
  23. void Kruskal(){
  24. int u,v,i,cnt=,mi=,ma=,flag=;
  25. init();
  26. for(i=;i<m;++i){
  27. u=e[i].u;
  28. v=e[i].v;
  29. if((u=fin(u))!=(v=fin(v))){
  30. f[u]=v;
  31. if(e[i].w) mi++;
  32. if(++cnt==n-){flag=;break;}
  33. }
  34. }
  35. if(!flag){printf("No\n");return;}
  36. init();
  37. for(i=m-;i>=;--i){
  38. u=e[i].u;
  39. v=e[i].v;
  40. if((u=fin(u))!=(v=fin(v))){
  41. f[u]=v;
  42. if(e[i].w) ma++;
  43. if(++cnt==n-)break;
  44. }
  45. }
  46. for(i=;i<;++i)
  47. if(mi<=fi[i]&&fi[i]<=ma){
  48. printf("Yes\n");return;
  49. }
  50. printf("No\n");
  51. }
  52. int main(){
  53. int t,i,a,b,c,k=;
  54. fi[]=;fi[]=;
  55. for(i=;i<;++i)
  56. fi[i]=fi[i-]+fi[i-];
  57. //printf(".%d.",fi[19]);
  58. scanf("%d",&t);
  59. while(t--){
  60. scanf("%d%d",&n,&m);
  61. for(i=;i<m;++i){
  62. scanf("%d%d%d",&a,&b,&c);
  63. e[i]={a,b,c};
  64. }
  65. sort(e,e+m,cmp);
  66. printf("Case #%d: ",k++);
  67. Kruskal();
  68. }
  69. return ;
  70. }

hdu5253 连接的管道(最小生成树)一开始我因为没建好图纠结了ToT~

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cmath>
  4. using namespace std;
  5. const int N=;
  6. struct edge{
  7. int u,v,w;
  8. }e[N*N*];
  9. int f[N*N];
  10. int g[N][N];
  11. int ei,n,m,ans;
  12. int cmp(edge a,edge b){
  13. return a.w<b.w;
  14. }
  15. int fin(int x){
  16. if(x!=f[x])f[x]=fin(f[x]);
  17. return f[x];
  18. }
  19. void Kruskal(){
  20. int u,v,i,cnt=;
  21. for(ans=i=;i<ei;++i){
  22. u=e[i].u;
  23. v=e[i].v;
  24. if((u=fin(u))!=(v=fin(v))){
  25. f[u]=v;
  26. ans+=e[i].w;
  27. if(++cnt==n*m-)break;
  28. }
  29. }
  30. }
  31. int main(){
  32. int t,i,j,h,k=;
  33. scanf("%d",&t);
  34. while(t--){
  35. ei=;
  36. scanf("%d%d",&n,&m);
  37. for(i=;i<n;++i){
  38. for(j=;j<m;++j){
  39. scanf("%d",&g[i][j]);
  40. f[i*m+j]=i*m+j;
  41. if(i>){
  42. e[ei].u=i*m+j; e[ei].v=(i-)*m+j;
  43. e[ei++].w=abs(g[i][j]-g[i-][j]);
  44. }
  45. if(j>){
  46. e[ei].u=i*m+j; e[ei].v=i*m+j-;
  47. e[ei++].w=abs(g[i][j]-g[i][j-]);
  48. }
  49. }
  50. }
  51. sort(e,e+ei,cmp);
  52. Kruskal();
  53. printf("Case #%d:\n%d\n",k++,ans);
  54. }
  55. return ;
  56. }

hdu1598 find the most comfortable road(最小生成树,枚举)第一眼看过去差点想最短路[吓],,这是最小差不是最短路哦。用Kruskal要对边排序,贪心正好哩。枚举最小道路建树,起点和终点连上了就记录最大边与最小边之差,最后选所有情况的最小值就行啦。

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cmath>
  4. using namespace std;
  5. const int inf=0x3f3f3f3f;
  6. const int M=;
  7. struct edge{
  8. int u,v,w;
  9. }e[M];
  10. int f[];
  11. int n,m,ans,st,ed;
  12. int cmp(edge a,edge b){
  13. return a.w<b.w;
  14. }
  15. void init(){
  16. for(int i=;i<=n;++i)
  17. f[i]=i;
  18. }
  19. int fin(int x){
  20. if(x!=f[x])f[x]=fin(f[x]);
  21. return f[x];
  22. }
  23. void Kruskal(){
  24. int u,v,i,j;
  25. ans=inf;
  26. for(i=;i<m;++i){//枚举
  27. init();
  28. for(j=i;j<m&&e[j].w-e[i].w<ans;++j){
  29. u=e[j].u;
  30. v=e[j].v;
  31. if((u=fin(u))!=(v=fin(v))){
  32. f[u]=v;
  33. }
  34. if(fin(st)==fin(ed)){
  35. ans=min(ans,e[j].w-e[i].w);
  36. break;
  37. }
  38. }
  39. }
  40. }
  41. int main(){
  42. int i,j,q;
  43. while(scanf("%d%d",&n,&m)==){
  44. for(i=;i<m;++i)
  45. scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
  46. sort(e,e+m,cmp);
  47. scanf("%d",&q);
  48. while(q--){
  49. scanf("%d%d",&st,&ed);
  50. Kruskal();
  51. printf("%d\n",(ans==inf)?-:ans);
  52. }
  53. }
  54. return ;
  55. }

poj3522 Slim Span(最小生成树,枚举)求最大边与最小边之差最小的生成树。和上面那题挺像的,相比之下,这题就是完整的最小生成树了。

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cmath>
  4. using namespace std;
  5. const int inf=0x3f3f3f3f;
  6. const int N=;
  7. struct edge{
  8. int u,v,w;
  9. }e[];
  10. int f[N];
  11. int n,m,ans,st,ed;
  12. int cmp(edge a,edge b){
  13. return a.w<b.w;
  14. }
  15. void init(){
  16. for(int i=;i<=n;++i)
  17. f[i]=i;
  18. }
  19. int fin(int x){
  20. if(x!=f[x])f[x]=fin(f[x]);
  21. return f[x];
  22. }
  23. void Kruskal(){
  24. int u,v,i,j,cnt;
  25. ans=inf;
  26. for(i=;i<m;++i){
  27. init(); cnt=;
  28. for(j=i;j<m&&e[j].w-e[i].w<ans;++j){
  29. u=e[j].u;
  30. v=e[j].v;
  31. if((u=fin(u))!=(v=fin(v))){
  32. f[u]=v;
  33. if(++cnt==n-){
  34. ans=min(ans,e[j].w-e[i].w);
  35. break;
  36. }
  37. }
  38. }
  39. }
  40. }
  41. int main(){
  42. int i,j,q;
  43. while(scanf("%d%d",&n,&m),n||m){
  44. for(i=;i<m;++i)
  45. scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
  46. sort(e,e+m,cmp);
  47. Kruskal();
  48. printf("%d\n",(ans==inf)?-:ans);
  49. }
  50. return ;
  51. }

poj2784 Buy or Build(最小生成树,二进制枚举)英语渣在艰难地读题orz。已知n个城市的坐标,q个连通块各自的费用,新建一条边的费用为两点距离的平方。求最小生成树。学了一下二进制枚举法。

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<vector>
  4. using namespace std;
  5. const int N=;
  6. struct edge{
  7. int u,v,w;
  8. }e[];
  9. struct node{
  10. int x,y;
  11. }V[N];
  12. int f[N];
  13. int a[];
  14. int n,m,q;
  15. vector<int>g[];
  16. int cmp(edge a,edge b){
  17. return a.w<b.w;
  18. }
  19. int dist(int i,int j){
  20. return (V[i].x-V[j].x)*(V[i].x-V[j].x)+(V[i].y-V[j].y)*(V[i].y-V[j].y);
  21. }
  22. void init(){
  23. for(int i=;i<=n;++i)
  24. f[i]=i;
  25. }
  26. int fin(int x){
  27. if(x!=f[x])f[x]=fin(f[x]);
  28. return f[x];
  29. }
  30. void uni(int x,int y){
  31. if((x=fin(x))==(y=fin(y)))return;
  32. f[x]=y;
  33. }
  34. int Kruskal(){
  35. int u,v,i,j,cnt=,ans=;
  36. for(i=;i<m;++i){
  37. u=e[i].u;
  38. v=e[i].v;
  39. if((u=fin(u))!=(v=fin(v))){
  40. f[u]=v;
  41. ans+=e[i].w;
  42. if(++cnt==n-)break;
  43. }
  44. }
  45. //printf("%d..\n",ans);
  46. return ans;
  47. }
  48. void solve(){
  49. int i,j,k,cost,ans;
  50. init();
  51. ans=Kruskal();
  52. for(i=;i<(<<q);++i){//枚举方案
  53. cost=;
  54. init();
  55. for(j=;j<q;++j){
  56. if(!((i>>j)&))continue;//二进制枚举
  57. cost+=a[j];
  58. //printf("COST:%d..",cost);
  59. for(k=;k<g[j].size();++k)
  60. uni(g[j][k],g[j][]);
  61. }
  62. ans=min(ans,cost+Kruskal());
  63. }
  64. printf("%d\n",ans);
  65. }
  66. int main(){
  67. int i,j,num,x;
  68. while(scanf("%d%d",&n,&q)==){
  69. for(i=;i<q;++i){
  70. g[i].clear();
  71. scanf("%d%d",&num,&a[i]);
  72. for(j=;j<num;++j){
  73. scanf("%d",&x);
  74. g[i].push_back(x);
  75. }
  76. }
  77. for(i=;i<=n;++i) scanf("%d%d",&V[i].x,&V[i].y);
  78. m=;
  79. for(i=;i<n;++i){
  80. for(j=i+;j<=n;++j){
  81. e[m].u=i; e[m].v=j;
  82. e[m++].w=dist(i,j);
  83. }
  84. }
  85. sort(e,e+m,cmp);
  86. solve();
  87. }
  88. return ;
  89. }

最小生成树练习2(Kruskal)的更多相关文章

  1. 最小生成树之Prim Kruskal算法(转)

    最小生成树 首先,生成树是建立在无向图中的,对于有向图,则没有生成树的概念,所以接下来讨论的图均默认为无向图.对于一个有n个点的图,最少需要n-1条边使得这n个点联通,由这n-1条边组成的子图则称为原 ...

  2. 最小生成树(prim&kruskal)

    最近都是图,为了防止几次记不住,先把自己理解的写下来,有问题继续改.先把算法过程记下来: prime算法:                  原始的加权连通图——————D被选作起点,选与之相连的权值 ...

  3. 图的最小生成树(Prim、Kruskal)

    理论: Prim: 基本思想:假设G=(V,E)是连通的,TE是G上最小生成树中边的集合.算法从U={u0}(u0∈V).TE={}开始.重复执行下列操作: 在所有u∈U,v∈V-U的边(u,v)∈E ...

  4. 最小生成树模板【kruskal & prim】

    CDOJ 1966 Kruskal 解法 时间复杂度O(mlogm) m为边数,这里主要是边排序占时间,后面并查集还好 #include <cstdio> #include <cst ...

  5. 图-最小生成树算法之Kruskal及其Java实现

    1.Kruskal算法 Kruskal算法基于贪心,因此它追求的是近似最优解,也就是说由Kruskal得出的生成树并不一定是最优解. Kruskal算法求最小生成树的关键在于,每次选取图中权值最小(及 ...

  6. 最小生成树(II)与Kruskal算法

    为防止网页加载过慢,故分两章.上接https://www.cnblogs.com/Uninstalllingyi/p/10479470.html Kruskal算法——将森林合并成树 玩过瘟疫公司吗… ...

  7. 最小生成树算法 prim kruskal两种算法实现 HDU-1863 畅通工程

    最小生成树 通俗解释:一个连通图,可将这个连通图删减任意条边,仍然保持连通图的状态并且所有边权值加起来的总和使其达到最小.这就是最小生成树 可以参考下图,便于理解 原来的图: 最小生成树(蓝色线): ...

  8. poj1861 最小生成树 prim &amp; kruskal

    // poj1861 最小生成树 prim & kruskal // // 一个水题,为的仅仅是回味一下模板.日后好有个照顾不是 #include <cstdio> #includ ...

  9. 最小生成树 Prim算法 Kruskal算法实现

    最小生成树定义 最小生成树是一副连通加权无向图中一棵权值最小的生成树. 在一给定的无向图 G = (V, E) 中,(u, v) 代表连接顶点 u 与顶点 v 的边(即,而 w(u, v) 代表此边的 ...

  10. 最小生成树求法 Prim + Kruskal

    prim算法的思路 和dijkstra是一样的 每次选取一个最近的点 然后去向新的节点扩张 注意这里的扩张 不再是 以前求最短路时候的到新的节点的最短距离 而是因为要生成一棵树 所以是要连一根最短的连 ...

随机推荐

  1. c#扩展方法的理解(二:接口)

    namespace ExtensionInterfaceMethod { class Program { static void Main(string[] args) { //使用接口变量来调用扩展 ...

  2. linux系统:rm-rf执行以后,怎么办?我来教你恢复文件。

    记得我当时也犯过这个错误 rm -rf /* 傻傻的盯着屏幕看... 还好当时是在自己的虚拟机里,没什么数据,打镜像恢复回来就好了.今天看到这篇文章,备用!嗯 是的 万一哪天脑抽了 --------- ...

  3. ABAP基本数据类型、通用类型

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  4. zoj 1199 几何公式推导

    链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=199 Point of Intersection Time Limit:  ...

  5. 《Linux内核设计的艺术》学习笔记(一)从开机加电到加载三个汇编源码

      实验内核版本:0.11 ◆ 从开机到main函数的三步: ① 启动BIOS,准备实模式下的中断向量表和中断服务程序: ② 从启动盘加载OS程序到内存中,加载OS程序的工作就是利用第一步中的中断服务 ...

  6. Typescript的面向对象

    封装: var Greeter = (function () { function Greeter(message) { this.greeting = message; } Greeter.prot ...

  7. FLASH CC 2015 CANVAS (四)制作响应式设计(自适应)的项目

    注意 此贴 为个人边“开荒”边写,所以不保证就是最佳做法,也难免有错误(如果发现我会更新文章)! 正式教程会在后续开始更新 相信你在看了(第二节)(第三节)之后已经能够满足绝大多数的互动需求了.那么也 ...

  8. chubu

    python解释型语言,不需要编译成机器认可的二进制码,而是直接从源代码运行程序. python是基于c语言开发的. python很容易嵌入到其他语言. 中文注释,必须在前边加上注释说明 : #_*_ ...

  9. 记CVTE2014年春季招聘实习生求职历程

    进度:目前已经过了网测 明天一面,好紧张,人生第一次实习面试.据说只有一分钟. 网测; 首先在http://exam.cvte.com/ 注册了账号,然后填写相关的个人信息,这里要仔细填写,因为它最后 ...

  10. iOS - UIActivityViewController

    前言 NS_CLASS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED @interface UIActivityViewController : UIViewControl ...