ZOJ - 4045 District Division(树)

这里写图片描述
Sample Input
3
4 2
1 3
3 2
1 4
6 3
1 3
1 4
1 6
2 5
5 1
8 4
1 2
2 3
2 4
1 5
5 6
5 7
5 8
Sample Output
YES
1 4
2 3
NO
YES
4 3 2 1
5 6 7 8

题意:给一棵有n个节点的树,问是否能将树分成几个区域,每个区域k个节点,如果可以输出YES并输出每个区域的节点都是谁,否则输出NO

首先dfs计算每个节点子树的大小,然后直接遍历整棵树,判断其子树是否能整除k,能整除说明其子树可以被分为n/k个区域,否则不行,不行的情况可能是该节点被包含在某个区域内了,之后对比能整除的节点个数是否等于n/k的区域数量,如果相等说明可以分配,否则有多余节点导致一些区域不够凑k个节点。

如果可行,则深搜遍历之前记录的节点,输出即是区域内的节点名。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=100005;
int n,t,k;
vector<int>mp[maxn];
vector<int>ans;
bool vis[maxn];
int sum[maxn],fa[maxn];
void dfs1(int rt,int pre)
{
    sum[rt]=1;
    fa[rt]=pre;
    for(int i=0; i<mp[rt].size(); i++)
    {
        int v=mp[rt][i];
        if(mp[rt][i]!=pre)
        {
            dfs1(v,rt);
            sum[rt]+=sum[v];
        }
    }
}
void dfs2(int rt,int pre)
{
    if(sum[rt]%k==0)ans.push_back(rt),vis[rt]=true;
    for(int i=0; i<mp[rt].size(); i++)
        if(mp[rt][i]!=pre)
            dfs2(mp[rt][i],rt);
}
int dfs3(int rt,int pre)
{
    for(int i=0; i<mp[rt].size(); i++)
    {
        if(!vis[mp[rt][i]]&&mp[rt][i]!=pre)
        {
            printf(" %d",mp[rt][i]);
            dfs3(mp[rt][i],rt);
        }
    }
}
bool judge()
{
    if(ans.size()!=n/k)return false;
    return true;
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        int from,to;
        scanf("%d%d",&n,&k);
        ans.clear();
        for(int i=0; i<=n; i++)mp[i].clear();
        memset(vis,false,sizeof vis);
        for(int i=0; i<n-1; i++)
        {
            scanf("%d%d",&from,&to);
            mp[from].push_back(to);
            mp[to].push_back(from);
        }
        dfs1(1,0);
        dfs2(1,0);
        bool ju=judge();
        printf("%s\n",ju?"YES":"NO");
        if(ju)
        {
            for(int i=0; i<ans.size(); i++)
            {
                printf("%d",ans[i]);
                dfs3(ans[i],fa[ans[i]]);
                printf("\n");
            }
        }
    }
}
posted @ 2018-06-23 19:01  KuroNekonano  阅读(105)  评论(0编辑  收藏  举报