当前位置:   article > 正文

[蓝桥杯 2020 省 AB1] 网络分析

[蓝桥杯 2020 省 AB1] 网络分析

一开始写的暴力合并 卡n^2过的不是正解

看正解是类似 虚拟点+树形DP的思路 很巧妙 记录一下

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. using ll = long long;
  4. using pii = pair<int,int>;
  5. #define int long long
  6. const int N = 3e5+10;
  7. const int inf = 0x3f3f3f3f;
  8. const int mod = 1e9+7;
  9. int gcd(int a,int b){return b?a:gcd(b,a%b);}
  10. int lcm(int a,int b){return a*b/gcd(a,b);}
  11. int qmi(int a,int b,int mod){int res=1;while(b){if(b&1)res=res*a%mod;b>>=1;a=a*a%mod;}return res;}
  12. int n,q,m;
  13. int p[N];
  14. int dp[N];
  15. int find(int x){
  16. if(x!=p[x])p[x] = find(p[x]);
  17. return p[x];
  18. }
  19. int e[N],ne[N],w[N],h[N],idx;
  20. void add(int a,int b,int c=0){
  21. e[idx] = b,ne[idx] = h[a],w[idx] = c,h[a] = idx++;
  22. }
  23. void dfs(int u,int fa){
  24. dp[u]+=dp[fa];
  25. for(int i=h[u];~i;i=ne[i]){
  26. int j = e[i];
  27. dfs(j,u);
  28. }
  29. }
  30. void solve()
  31. {
  32. cin>>n>>m;
  33. int root = n+1;
  34. memset(h,-1,sizeof h);
  35. for(int i=1;i<=2*n+10;++i)p[i] = i;
  36. while(m--){
  37. int op,a,b;cin>>op>>a>>b;
  38. if(op==1){
  39. int pa = find(a),pb = find(b);
  40. if(pa==pb)continue;
  41. p[pa] = root;
  42. p[pb] = root;
  43. add(root,pa);
  44. add(root,pb);
  45. ++root;
  46. }else{
  47. dp[find(a)]+=b;
  48. }
  49. }
  50. for(int i=n+1;i<root;++i)if(find(i)==i)dfs(i,0);
  51. for(int i=1;i<=n;i++)cout<<dp[i]<<" ";
  52. }
  53. signed main()
  54. {
  55. ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
  56. int _;
  57. //cin>>_;
  58. _ = 1;
  59. while(_--)solve();
  60. return 0;
  61. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/330007
推荐阅读
相关标签
  

闽ICP备14008679号