codeforces 700B Connecting Universities

蛮有意思的。。。。考虑每条边的贡献。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxv 200500
#define maxe 400500
using namespace std;
int n,k,x,y,nume=0,g[maxv],size[maxv],fath[maxv];
long long ans=0;
bool vis[maxv];
struct edge
{
    int v,nxt;
}e[maxe];
void addedge(int u,int v)
{
    e[++nume].v=v;
    e[nume].nxt=g[u];
    g[u]=nume;
}
void dfs1(int x)
{
    size[x]=0;
    for (int i=g[x];i;i=e[i].nxt)
    {
        int v=e[i].v;
        if (v!=fath[x])
        {
            fath[v]=x;
            dfs1(v);
            size[x]+=size[v];
        }
    }
    if (vis[x]) size[x]++;
}
void dfs2(int x)
{
    for (int i=g[x];i;i=e[i].nxt)
    {
        int v=e[i].v;
        if (v!=fath[x])
        {
            ans+=min(size[v],2*k-size[v]);
            dfs2(v);
        }
    }
}
int main()
{
    scanf("%d%d",&n,&k);
    for (int i=1;i<=2*k;i++) {scanf("%d",&x);vis[x]=true;}
    for (int i=1;i<=n-1;i++)
    {
        scanf("%d%d",&x,&y);
        addedge(x,y);addedge(y,x);
    }
    dfs1(1);
    dfs2(1);
    printf("%I64d\n",ans);
    return 0;
}
时间: 2024-08-03 18:40:06

codeforces 700B Connecting Universities的相关文章

Codeforces 700B Connecting Universities - 贪心

Treeland is a country in which there are n towns connected by n - 1 two-way road such that it's possible to get from any town to any other town. In Treeland there are 2k universities which are located in different towns. Recently, the president signe

Codeforces 700B Connecting Universities(树形DP)

[题目链接] http://codeforces.com/problemset/problem/700/B [题目大意] 给出 一棵n个节点的树, 现在在这棵树上选取2*k个点,两两配对,使得其配对的两点间距离的和最大. [题解] 求出树的加权重心,那么答案就是每个点到加权重心的距离之和,但是实际上,并不需要求出加权重心,观察树边和其两边的询问节点,可以发现一个优美的性质,每条边对答案的贡献值为min(左边的点数,右边的点数),因此,树规计算每条边的贡献值,累加和就是答案. [代码] #incl

codeforces 700B Connecting Universities 贪心dfs

分析:这个题一眼看上去很难,但是正着做不行,我们换个角度:考虑每条边的贡献 因为是一棵树,所以一条边把树分成两个集合,假如左边有x个学校,右边有y个学校 贪心地想,让每条边在学校的路径上最多,所以贡献为min(x,y) 具体实现:一次dfs即可,复杂度O(N) #include <stdio.h> #include <iostream> #include <algorithm> #include <string.h> #include <vector&

Codeforces Round #364 (Div. 1)B. Connecting Universities

题目链接:传送门 题目大意:n个点构成一棵树,给定 k*2 点,要分成 k 组,使每组点之间的距离之和最大. 题目思路:因为是求距离之和最大,所以我们可以知道这样一个性质.如果以一条边为界,两边的子树均有给定的点,则这条边一定会经过 min(左边的给定点数,右边的给定点数)次. 那么这条边的贡献就是经过的次数. #include <iostream> #include <cstdio> #include <cstdlib> #include <cmath>

B. Connecting Universities DFS,无向树

http://codeforces.com/problemset/problem/700/B 题意是,在一颗树中,有k个大学,要求两两匹配,他们之间的距离作为贡献,使得距离总和最大. 一开始的时候无从下手,一路在想某一个点应该和哪一个点去匹配.但是这样是错误的思路. 正解是观察边的贡献,如果某两个学校连接了,那么肯定有一条路径的,这条路径会经过很多的边,我们把经过某条边的次数统计出来.那么答案就是这棵树的边的权值和. 那怎么算一条边的贡献呢. 贪心地去想, 某一条边,把整颗树分成了两部分,那么第

cf701E Connecting Universities

Treeland is a country in which there are n towns connected by n?-?1 two-way road such that it's possible to get from any town to any other town. In Treeland there are 2k universities which are located in different towns. Recently, the president signe

Connecting Universities

Treeland is a country in which there are n towns connected by n - 1 two-way road such that it's possible to get from any town to any other town. In Treeland there are 2k universities which are located in different towns. Recently, the president signe

【CF700B】Connecting Universities(想法题,贪心,树上最短路)

题意:给出一棵树上的2*k个节点,给他们配对,使得他们之间的距离和最大. 思路:一条边的两侧如果有一侧没有给定的节点就不会被经过…… 如果有1个节点就会被经过1次…… 如果两侧分别有x,y个给定节点就会被经过min(x,y)次 因为要使总路程最大就是让每一条路被走过最多的次数 肯定是两侧各取一个 剩下的只能在某侧内部解决 所以按此统计即可 答案很大 用INT64 1 var head,vet,next,a,b,c,dep,flag,f:array[1..500000]of longint; 2

cf 700 B Connecting Universities

题意:现在给以一棵$n$个结点的树,并给你$2k$个结点,现在要求你把这些节点互相配对,使得互相配对的节点之间的距离(路径上经过边的数目)之和最大.数据范围$1 \leq n \leq 200000, 2k \leq n$. 分析:贪心选择距离最大.次大...的结点对?貌似不对.暴力枚举所有可能?对但不可行.考虑节点对之间的距离实际上就是它们到LCA距离之和.因此单独考虑每个结点,它对答案的贡献实际上就是它到与其匹配节点的LCA的距离,这个距离必然不超过它到根的距离.如果我们有一种方法使得每个结