【重点】Codeforces Round #364 (Div. 2)

来源:互联网 发布:淘宝运营服务商 个人 编辑:程序博客网 时间:2024/06/07 10:40

唉,有一场很好加分的场没加多少
确实如出题人所说,用各个难度梯度的简单题出了,但是只能说自己太菜了。

前40min ABC 都过了,都是乱搞题

D 推公式 推了好久都是错的,可能是半夜脑子不好使,居然在第二天发现推的公式对了大半,最后输出结果产生了问题,也是醉了。

E 主要想讲一下E, 赛后看了看hx的代码,觉得好厉害啊。 按这种想法写出来的代码简单,但是我不知道证明这种想法的正确性,模模糊糊的感觉应该是对的

题意:
给你一棵树 包含n个点,然后给你 2*k 个点, 要你从这2k个点中 选出k对点,使得k对点 距离和 最大。
n<2*1e5 k<=n/2
然后我想了一下, 点边都是10W,不太可能直接跑出来。

想一下 在一棵树中,从2*k中选出k对,求出每一对u,v 之间的距离。那么u,v必然不能在同一棵子树中,因为 假如在另外一颗子树中选出x,y 这样的话dis(u,v)+dis(x,y) < dis(u,x)+dis(v,y) 或者 dis(u,y)+dis(v,x)

照这个想法,我们只要选出一个root 建树,然后我们保证 root 的每一子树的所有被标记的节点数目 都 <= k ,因为如果某个子树的标记节点数目>k,那么就肯定有点无法和其他子树节点匹配到。

但是我并不知道 这个root 是不是一定存在,讲道理是应该存在的。

然后建好树,我们就只需要跑出来每个标记节点到root的距离,相加就好

#include<iostream>#include<stdio.h>#include<string.h>#include<math.h>#include<algorithm>#include<stdlib.h>#include<queue>#include<stack>#include<map>#include<vector>#define mem(a) memset(a,0,sizeof(a))#define pfn printf("\n")#define ll __int64#define pfd(a) printf("%d\n",a)#define pf2d(a,b) printf("%d %d\n",a,b)#define pf3d(a,b,c) printf("%d %d %d\n",a,b,c)#define pfs(a) printf("%s\n",a)#define sfd(a) scanf("%d",&a)#define sf2d(a,b) scanf("%d%d",&a,&b)#define sf3d(a,b,c) scanf("%d%d%d",&a,&b,&c)#define sfs(a) scanf("%s",a)#define sf    scanf#define pf    printf#define fr(i,n) for(int i=0;i<n;i++)const double PI = acos(-1.0);const double e = exp(1.0);template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }template<class T> T lcm(T a, T b) { return a / gcd(a, b) * b; }template<class T> inline T Min(T a, T b) { return a < b ? a : b; }template<class T> inline T Max(T a, T b) { return a > b ? a : b; }bool cmpbig(int a,int b){return a>b;}bool cmpsmall(int a,int b){return a<b;}using namespace std;#define clean(a) memset(a, 0, sizeof(a))const int maxn = 200100;int n, k, root, w[maxn], size[maxn];ll len[maxn];vector<int> g[maxn];void dfs(int t, int fa){    size[t] = w[t];    bool flag = 1;    for(int i=0;i<g[t].size();i++){        int v=g[t][i];        if(v != fa){            dfs(v, t);            size[t] += size[v];            if(size[v] > k) flag = 0;        }    }    if(2 * k - size[t] > k) flag = 0;    if(flag) root = t;}int dir[maxn];void DFS(int t, int fa){    for(int i=0;i<g[t].size();i++){        int v=g[t][i];        if(v != fa){            dir[v]=dir[t]+1;            DFS(v, t);        }    }}int main(){    //freopen("1.txt","r",stdin);    scanf("%d%d", &n, &k);    for(int i = 1; i <= 2 * k; ++i){        int u;        scanf("%d", &u);        w[u]++;    }    for(int i = 1; i < n; ++i){        int u, v;        scanf("%d%d", &u, &v);        g[u].push_back(v), g[v].push_back(u);    }    dfs(1, 0);//  printf("root=%d\n",root);    dir[root]=0;    DFS(root, 0);    __int64 ans=0;    for(int i=1;i<=n;i++)        if(w[i]>0){            ans+=dir[i];        }    printf("%I64d\n", ans);  return 0;}
0 0
原创粉丝点击