/*
先建树,然后对树进行后序遍历假设nodes[i].score表示以i为根的子树需要的石头数,则
(1)对于叶子节点其score为1
(2)对于非叶子节点,先将其所有子节点按照其所需score数降序排序,然后遍历其子节点
int need = 0, rest = 0, need表示遍历到当前子树需要的石头数,rest表示剩下的石头数
for( sid : i's sons)
int sid = nodes[id].sons[k];
//处理当前节点需要的数目
int curNeed = nodes[sid].score - rest;
if(curNeed < 0) curNeed = 0;
//更新需要的总数
need += curNeed;
//更新剩下的石头数
rest = rest + curNeed - 1;
则i节点需要的石头数即为need,返回即可
*/
#include <iostream>
#include <algorithm>
#define MAX_N 205
using namespace std;
struct node
{
int id, score, sonNum;
int sons[MAX_N + 1];
node()
{
id = score = 0;
}
}nodes[MAX_N + 1];
int n;
void init()
{
for(int i = 1; i <= n; i++)
{
nodes[i].id = i;
nodes[i].score = nodes[i].sonNum = 0;
}
}
bool compare(const int n1, const int n2)
{
if(nodes[n1].score >= nodes[n2].score) return true;
else return false;
}
int getScore(int id)
{
if(nodes[id].sonNum == 0) return nodes[id].score = 1;
else
{
for(int s = 1; s <= nodes[id].sonNum; s++)
getScore(nodes[id].sons[s]);
sort(nodes[id].sons + 1, nodes[id].sons + 1 + nodes[id].sonNum, compare);
int need = 0, rest = 0;
for(int k = 1; k <= nodes[id].sonNum; k++)
{
int sid = nodes[id].sons[k];
int curNeed = nodes[sid].score - rest;
if(curNeed < 0) curNeed = 0;
need += curNeed;
rest = rest + curNeed - 1;
}
return nodes[id].score = need;
}
}
int main()
{
int caseNum, i, j;
scanf("%d", &caseNum);
while(caseNum--)
{
init();
scanf("%d", &n);
for(i = 1; i <= n; i++)
{
int from, to, sn;
scanf("%d%d", &from, &sn);
for(j = 1; j <= sn; j++)
{
scanf("%d", &to);
int p = ++nodes[from].sonNum;
nodes[from].sons[p] = to;
}
}
printf("%d/n", getScore(1));
}
return 0;
}
POJ 1694 An Old Stone Game
最新推荐文章于 2019-05-20 15:20:23 发布