东大oj1159 Friends

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了东大oj1159 Friends相关的知识,希望对你有一定的参考价值。

Problem Description

In a country, the relationship between people can be indicated by a tree. If two people are acquainted with each other, there will be an edge between them. If a person can get in touch with another through no more than five people, we should consider these two people can become friends. Now, give you a tree of N people’s relationship. ( 1 <= N <= 1e5), you should compute the number of who can become friends of each people?

Input

In the first line, there is an integer T, indicates the number of the cases.

For each case, there is an integer N indicates the number of people in the first line.

In the next N-1 lines, there are two integers u and v, indicate the people u and the people v are acquainted with each other directly.

People labels from 1.

Output

For each case, the first line is “Case #k :”, k indicates the case number.

In the next N lines, there is an integer in each line, indicates the number of people who can become the ith person’s friends. i is from 1 to n.

 

大意是在加♂帕♂里♂大♂草♂原(自我告诫)上,有很多friends,给出两两的friends关系,两个人如果有通过不超过5个人的friends关系,就能成为friends,输出每个人能和多少人成为friends。

没思路,强行写的话就对每个点都搜,多半超时

怕是dp的思想,看了学长的代码后强行理解了...

关键两个转移方程:ch[u][j] += ch[v][j-1],  fa[u][i] = fa[f][i-1] + ch[f][i-1] - ch[u][i-2];

统计ch时是先搜到底,从下往上算;统计fa时一边往下搜一边算,十分机智

算fa的时候根节点特殊处理下

 

#include<cstdio>
#include<cstring>
const int maxn = 200007;
struct Edge
{
    int v, next;
}E[maxn];
int head[maxn], fa[maxn][10], ch[maxn][10];//fa[i][j]保存从i点向上距离为j的点的数目,ch是向下
int n, cur;
void addedge(int u, int v)
{
    E[cur].v = v;
    E[cur].next = head[u];
    head[u] = cur++;
}
void dfsch(int u, int f)
{
    for(int i = head[u]; ~i; i = E[i].next)
    {
        int v = E[i].v;
        if(v == f)
            continue;
        dfsch(v, u);
        for(int j = 1; j <= 6; j++)
        {
            ch[u][j] += ch[v][j-1];//关键的转移
        }
    }
    ch[u][0] = 1;
}
void dfsfa(int u, int f)
{
    fa[u][0] = 1;
    if(u != f)//根节点特殊处理下
    {
        fa[u][1] = 1;//一个点的父节点只有一个对吧
        for(int i = 2; i <= 6; i++)
        {
            fa[u][i] = fa[f][i-1] + ch[f][i-1] - ch[u][i-2];// 关键的转移
        }
    }
    for(int i = head[u]; ~i; i = E[i].next)
    {
        int v = E[i].v;
        if(v != f)
            dfsfa(v, u);
    }
}
void ini()
{
    memset(head, -1, sizeof(head));
    memset(fa, 0, sizeof(fa));
    memset(ch, 0, sizeof(ch));
    cur = 0;
}
int main()
{
    //freopen("in.txt", "r", stdin);
    int t;
    int kase = 1;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d", &n);
        ini();
        for(int i = 1; i <n; i++)
        {
            int u, v;
            scanf("%d%d", &u, &v);
            addedge(u, v);
            addedge(v, u);
        }
        dfsch(1, 1);
        dfsfa(1, 1);
        printf("Case #%d:\n", kase++);
        for(int i = 1; i <= n; i++)
        {
            int ans = 0;
            for(int j = 1; j <= 6; j++)
            {
                ans += ch[i][j];
                ans += fa[i][j];
            }
            printf("%d\n", ans);
        }
    }
    return 0;
}

 

以上是关于东大oj1159 Friends的主要内容,如果未能解决你的问题,请参考以下文章

东大OJ1171题:ACMER的出行计划

OJ 1159 holiday

西安东大肛肠医院黑心骗人医院收费很低,诋毁东大

九度oj 题目1397:查找数段

HDOJ1159解题报告

HDU-1159-Common Subsequence