首页 > 其他分享 >AtCoder Beginner Contest 214

AtCoder Beginner Contest 214

时间:2023-08-11 21:45:54浏览次数:38  
标签:AtCoder 214 Beginner sz int long fa

AtCoder Beginner Contest 214 - AtCoder


 

[ABC214D] Sum of Maximum Weights ------------------------------( 典 )

题意:给出一颗 N - 1 条边的树,求树上任意两点间路径上的最大值的和

这种问题考虑每条边单独看贡献,但是刚开始没太想明白怎么计算贡献,后面看了洛谷题解才懂了

----------------------------------------------------------------------------------------------------------------------------------------

也就是说加入边 s 是一条连通点 a,b 路径上的最大一条边,那么 a,b两点路径上的边一定是小于 s 的权值的

若对所有边权排了个序,s一定是 a 到 b路径上最后一个加入的边,那么此时用一个并查集维护,sz[ a ] 就是在边权小于s的情况下有多少个点是可以到达 a 的,同理sz[ b ]

那么由乘法原理就可以计算出 a 到 b 有多少种方案(sz[ a ] * sz[ b ]),贡献也就算出来了

 

#include<bits/stdc++.h>
using namespace std;
#define endl "\n"
#define int long long
typedef long long ll;

const int N = 1e5 + 5;

struct Node{
    int x, y, v;
}a[N];

bool cmp(Node a,Node b){
    return a.v < b.v;
}

int fa[N], sz[N];

int Findset(int x){
    return (x == fa[x]) ? x : fa[x] = Findset(fa[x]);
}

signed main(){
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int n; cin >> n;
    for(int i = 1; i < n; i++){
         cin >> a[i].x >> a[i].y >> a[i].v;
    }
    for(int i = 1; i <= n; i++)fa[i] = i, sz[i] = 1;
    sort(a + 1, a + n, cmp);
    int  ans = 0;
    for(int i = 1; i < n; i++){
        int x = a[i].x, y = a[i].y, v = a[i].v;
        int fx = Findset(x), fy = Findset(y);
        //fx != fy其实是不必要的
        if(fx != fy){
            ans += sz[fx] * sz[fy] * v;
            sz[fx] += sz[fy];
            sz[fy] = 0;
            fa[fy] = fx;
        }
    }
    cout << ans;
    return 0;
}
View Code

 

标签:AtCoder,214,Beginner,sz,int,long,fa
From: https://www.cnblogs.com/zhujio/p/17623995.html

相关文章

  • Atcoder杂题笔记
    大概会把博客当草稿纸用(当然写出正解还是会把正解贴出来。[ARC080E]YoungMaids(待补代码)给定正偶数\(N\)。给定\(N\)元排列\(p=(p_1,p_2,...,p_N)\).Snuke打算根据下述步骤构造一个\(N\)元排列\(q\)。首先,令\(q\)为空。接下来,执行下述操作直到\(p\)为空......
  • Atcoder ABC307_G-Approximate Equalization 序列dp
    AT_ABC307_G-ApproximateEqualization没想到还有ApproximateEqualizationII!!:AT_ABC313_CDescription:给定一个长度为\(N\)的数列:\(A=(A_1,A_2,···,A_N)\),有两种操作可以以任意顺序进行任意多次(可以为0):\(A[i]-\)=\(1\)且\(A[i+1]+\)=\(1\),\((1\leqi\leqN-1)......
  • AtCoder-ARC073_A Sentou
    Sentou【题意】:有一个开关,当按下开关后的T秒内会一直放水,当在放水状态时,如果有人再次按下开关,那么停止放水,并从按下的那一刻起的T秒会再次一直放水,给出n个人按压开关的时间,问总共流出多少水【思路】:简单模拟#include<bits/stdc++.h>usingnamespacestd;typedeflon......
  • AtCoder Beginner Contest 313
    AtCoderBeginnerContest313A-ToBeSaikyo思路:找到最大的,和第一个比较#include<bits/stdc++.h>usingnamespacestd;#defineintlonglong//#defineint__int128#definedoublelongdoubletypedefpair<int,int>PII;typedefpair<string,int>PSI;t......
  • AtCoder Beginner Contest 313
    AtCoderBeginnerContest313-AtCoderA-ToBeSaikyo(atcoder.jp)从\(a_1\dotsa_{n-1}\)找出最大值与\(a_0\)比较即可#include<bits/stdc++.h>#defineintlonglong#defineendl'\n'usingnamespacestd;signedmain(){ios::sync_with_st......
  • 取数游戏 Atcoder-abc128_d
    枚举两端取了几个数,将手中的负数从小到大放回序列即可#include<bits/stdc++.h>usingnamespacestd;intn,m,a[55],c[55],ans=-0x7fffffff;intmain(){scanf("%d%d",&n,&m);for(inti=1;i<=n;i++)scanf("%d",&a[i]);f......
  • Atcoder Grand Contest 058 F - Authentic Tree DP
    考虑给\(f(T)\)赋予组合意义。一个直观的想法是,在每条边中间新建一个节点,然后每次选择一条边对应的点,然后把它删掉,递归剩余的两个部分,但是你会发现这样分母不对,应该是\(n\)但在这个模型里只有\(n-1\)。考虑魔改这个模型。我们在每个边对应的点下面添加\(998244352\)个点,你......
  • Atcoder ABC313_C-Approximate Equalization 2
    AT_ABC313_C-ApproximateEqualization2Description:给定一个整数序列\(A=(A_1,A_2,···,A_n)\),可以做以下操作任意次(可能为0):选择一个整数对\((i,j)\)\((1\leqi,j\leqn)\),使得\(A[i]-\)=\(1\),\(A[j]+\)=\(1\),求出使得数列\(A\)中的\(max-min\leq1\)所需的最少......
  • Atcoder Beginner Contest 313
    CDEF有\(n(1\len\le40)\)张牌,每一张牌正面写上了数字\(a_i\),背面写上了数字\(b_i\)。最初所有牌都是正面朝上。有\(m\)个机器,每个机器有参数\(x_i,y_i(1\lex_i,y_i\len)\),\(x_i\)可以等于\(y_i\)。每个机器只能启动一次,并且有\(\frac{1}{2}\)的概率将牌\(......
  • AtCoder Beginner Contest 313
    A-ToBeSaikyo#include<bits/stdc++.h>usingnamespacestd;intmain(){ ios::sync_with_stdio(0),cin.tie(0); intn; cin>>n; vector<int>a(n); for(auto&i:a)cin>>i; cout<<max(0,*max_element(a.beg......