East Central North America 2005——Countdown

East Central North America 2005——Countdown

题目来源:

题意:

给你一个系谱图,问你某代子孙最多的三个人是谁以及他们的某代子孙有多少个(相同全部输出,按名字字典序),小于三个全部输出。

题解:

写法一:

使用大量的模板进行建树等操作,暴力dfs搜索,对结果处理输出即可。

此法太无脑,不写了

写法二:

建树时记录id,dfs时记录路径(id顺序),直接对某代前的祖先更新,处理结果,输出。注意get_id的思想和用法。

#include <bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
struct Node
{
    string s;
    int num;
}fa[1111];

int n,d,vi[1111];
map<string,int> mp;
int all=1;
string str1,str2;
vector<int> edge[1111];

bool cmp(Node a,Node b)
{
    if(a.num==b.num)
        return a.s<b.s;
    return a.num>b.num;
}

int get_id(string s)
{
    if(mp[s]==0)
    {
        mp[s]=all;
        fa[all].s=s;
        fa[all].num=0;
        all++;
    }
    return mp[s];
}

int dfs(int x,int d)
{
    if(d==0)
        return 1;
    int ans=0;
    for(int i=0;i<edge[x].size();i++)
        ans+=dfs(edge[x][i],d-1);
    return ans;
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("B.in","r",stdin);
    //freopen("B-0.out","w",stdout);
#endif
    int T;
    cin >> T;
    for(int cas=1;cas<=T;cas++)
    {
        printf("Tree %d:\n",cas);
        cin >> n>>d;
        mp.clear();
        all=1;
        memset(vi,0,sizeof(vi));
        for(int i=0;i<1111;i++)
            edge[i].clear();
        for(int i=0;i<n;i++)
        {
            int m;
            cin >> str1>>m;
            for(int j=0;j<m;j++)
            {
                cin >>str2;
                edge[get_id(str1)].push_back(get_id(str2));
            }
        }
        for(int i=1;i<all;i++)
        {
            fa[i].num=dfs(i,d);
        }
        sort(fa+1,fa+all,cmp);
        int ccc=0x3f3f3f;
        for(int i=1;i<=min(3,all-1);i++)
        {
            if(fa[i].num==0)
                break;
            vi[i]=1;
            ccc=fa[i].num;
            cout << fa[i].s <<" "<<fa[i].num<<endl;
        }
        for(int i=1;i<all;i++)
        {
            if(vi[i]==1)
                continue;
            if(fa[i].num<ccc)
                break;
            if(fa[i].num==ccc)
            {
                cout <<fa[i].s<<" " << fa[i].num<<endl;
            }
        }
        cout << endl;
    }
    return 0;
}

转载于:https://www.cnblogs.com/Combustible-ice/p/5835875.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值