分治算法

妖狐艹你老母 2021-10-24 00:20 450阅读 0赞

可能我太菜了 ,众多题解 的t0*t0 +t1*t2*2始终没看懂

分治大模拟好!

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int INF = 1000000000;
  5. const int M=20010;
  6. struct Node{ int next,to,w;}e[M*2];
  7. int n,head[M*2],siz[M],cnt,sum,mp,rt,v[M],dis[M],judge[5];
  8. ll res=0,ans=0,tem;
  9. ll gcd(ll a,ll b){
  10. if(a<b)swap(a,b);
  11. return b?gcd(b,a%b):a;
  12. }
  13. void add(int x,int to,int w){
  14. e[cnt].to=to;
  15. e[cnt].w=w;
  16. e[cnt].next=head[x];
  17. head[x]=cnt++;
  18. }
  19. void getrt(int x,int fa){
  20. siz[x]=1;
  21. int mm=0;
  22. for(int to,i=head[x];~i;i=e[i].next){
  23. to=e[i].to;
  24. if(v[to]||fa==to)continue;
  25. getrt(to,x);
  26. siz[x]+=siz[to];
  27. mm=max(mm,siz[to]);
  28. }
  29. mm=max(sum-siz[x],mm);
  30. if(mp>mm)mp=mm,rt=x;
  31. }
  32. void dfs(int x,int fa){
  33. siz[x]=1;
  34. int mm=0;
  35. for(int to,i=head[x];~i;i=e[i].next){
  36. to=e[i].to;
  37. if(v[to]||fa==to)continue;
  38. dfs(to,x);
  39. siz[x]+=siz[to];
  40. }
  41. }
  42. void getdis(int x,int fa,int w){
  43. for(int to,i=head[x];~i;i=e[i].next){
  44. to=e[i].to;
  45. if(v[to]||to==fa)continue;
  46. dis[++dis[0]]=(e[i].w+w)%3;
  47. getdis(to,x,dis[dis[0]]);
  48. }
  49. }
  50. void work(int x){
  51. v[x]=1;
  52. judge[0]=1;
  53. for(int to,i=head[x];~i;i=e[i].next){
  54. to=e[i].to;
  55. if(v[to])continue;
  56. dis[dis[0]=1]=e[i].w;
  57. getdis(to,x,dis[dis[0]]);
  58. for(int j=dis[0];j;j--)res+=judge[(3-dis[j])%3];
  59. for(int j=dis[0];j;j--)judge[dis[j]]++;
  60. }
  61. memset(judge,0,sizeof(judge));
  62. }
  63. void slove(int x){
  64. work(x);
  65. for(int to,i=head[x];~i;i=e[i].next){
  66. to=e[i].to;
  67. if(v[to])continue;
  68. sum=siz[to];mp=INF;
  69. getrt(to,0);
  70. dfs(rt,0);
  71. slove(rt);
  72. }
  73. }
  74. int main(){
  75. cnt=1;memset(head,-1,sizeof(head));
  76. scanf("%d",&n);
  77. for(int x,y,z,i=1;i<n;i++){
  78. scanf("%d%d%d",&x,&y,&z);
  79. z%=3;
  80. add(x,y,z);
  81. add(y,x,z);
  82. }
  83. mp=INF;sum=n;
  84. getrt(1,0);
  85. dfs(rt,0);
  86. slove(rt);
  87. res=res+res+n;
  88. ans=n*n;
  89. tem=gcd(ans,res);
  90. cout<<res/tem<<"/"<<ans/tem;
  91. return 0;
  92. }

发表评论

表情:
评论列表 (有 0 条评论,450人围观)

还没有评论,来说两句吧...

相关阅读

    相关 算法-分治算法

    一、分治 1、定义:分治,也就是分而治之。 它的一般步骤是: ① 将原问题分解成若干个规模较小的子问题(子问题和原问题的结构一样,只是规模不一样)

    相关 算法思想-分治算法

    tip:作为程序员一定学习编程之道,一定要对代码的编写有追求,不能实现就完事了。我们应该让自己写的代码更加优雅,即使这会费时费力。 推荐:[体系化学习Java(Java面试专

    相关 分治算法

    问题描述 在一个2k×2k 个方格组成的棋盘中,恰有一个方格与其它方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,要用图示的L型骨牌覆盖给定的特

    相关 分治算法

    [概述参考博客地址][Link 1] [算法笔记总目录][Link 2] 一、分治算法的设计思想: 1. 分–将问题分解为规模更小的子问题; 2. 治–将这些规

    相关 分治算法

    划分问题:整个问题划分成多个无关联的子问题。 递归求解:递归调用求解各个子问题。 合并问题:合并子问题的解,形成原始问题的解。 -------------------

    相关 分治算法

    分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解。即一种分目标完成程序算法,简单问题

    相关 分治算法

    分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解。即一种分目标完成程序算法,简单问题

    相关 分治算法

    一 分治算法介绍 1 分治法是一种很重要的算法 字面上的解释是“分而治之,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……,直