2017 Multi-University Training Contest

来源:互联网 发布:了不起的nodd.js 编辑:程序博客网 时间:2024/06/01 10:38

题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=6178

题目大意

给你一颗树, 有n个节点, 给你a1……an-1, 表示ai和i+1有一条边, 有k只猴子, 每个节点只能有一只猴子, 问你最多可以去掉多少边, 使得每只猴子通过剩下的边都能至少连接一只猴子, 输出剩下边的条数

思路

两个两个匹配就行了, 由于是颗树, 标记一下儿子就行了
这题卡了读入,简直妙(sang)不(xin)可(bing)言(kuang)
直接上快速读入模板

代码

#include<bits/stdc++.h>#define fi first#define se second#define lson l,mid,o<<1#define rson mid+1,r,o<<1|1using namespace std;typedef long long LL;typedef unsigned long long uLL;typedef pair<int, int> PII;const LL INF = 0x3f3f3f3f;const int MAX_N = 1e5 + 10;const LL mod = 1e9 + 7;const double PI=acos(-1);namespace IO {    const int MX = 4e7; //1e7 占用内存 11000kb    char buf[MX]; int c, sz;    void begin() {        c = 0;        sz = fread(buf, 1, MX, stdin);    }    inline bool read(int &t) {        while (c < sz && buf[c] != '-' && (buf[c] < '0' || buf[c] > '9')) c++;        if (c >= sz) return false;        bool flag = 0; if(buf[c] == '-') flag = 1, c++;        for(t = 0; c < sz && '0' <= buf[c] && buf[c] <= '9'; c++) t = t * 10 + buf[c] - '0';        if(flag) t = -t;        return true;    }}int to[MAX_N];bool node[MAX_N];int main(){    int cas, n, m, u, tot;    IO::begin();    IO::read(cas);    memset(node, false, sizeof(node));    while(cas--){        IO::read(n), IO::read(m);        for(int i = 2; i <= n; ++i) IO::read(to[i]);        tot = 0;        for(int i = n; i >= 1; --i)            if(!node[i])    node[to[i]] = true;            else tot++, node[i] = false;        if(tot * 2 >= m)    printf("%d\n", m - (m >> 1));        else    printf("%d\n", m - tot);    }    return 0;}