V8ORG spoj – Tổ chức đối lập

Nguồn đề bài: http://vn.spoj.com/problems/V8ORG/

1. Đề bài V8ORG spoj

Ở một đất nước nọ, lực lượng an ninh vừa phát hiện một tổ chức đối lập. Tổ chức đối lập này được tổ chức chặt chẽ, bao gồm mạng lưới thành viên và chỉ huy ở các cấp bậc khác nhau. Các thành viên của tổ chức được đánh số từ 1 đến N. Tổ chức có một chỉ huy tối cao, luôn được đánh số 1. Mỗi thành viên chỉ biết viên chỉ huy trực tiếp của mình (có duy nhất một viên chỉ huy trực tiếp) chứ không biết các chỉ huy cấp cao hơn.

Khi tiến hành việc bắt giữ các thành viên, tổ chức sẽ bị phân rã thành các nhóm nhỏ không liên kết với nhau, ví dụ sau khi bắt giữ thành viên số 2 (hình 1), tổ chức bị phân rã thành 4 nhóm. Lực lượng an ninh khẳng định, một nhóm chứa ít hơn K thành viên sẽ không còn là mối đe dọa cho đất nước. Để không làm giảm hình ảnh của đất nước trước dư luận quốc tế, các nhà lãnh đạo an ninh muốn bắt giữ một số lượng ít nhất phần tử đối lập, sao cho các nhóm bị phân rã đều không còn gây nguy hại cho đất nước.

Cho biết cấu trúc của tổ chức đối lập, việc chương trình giúp các nhà lãnh đạo an ninh xác định số lượng phần tử đối lập ít nhất cần bắt giữ.

Dữ liệu

  • Dòng đầu tiên chứa số nguyên K (1 ≤ K ≤ 10000).
  • Dòng thứ hai chứa số nguyên N (1 ≤ N ≤ 10000).
  • Dòng thứ ba chứa N-1 số nguyên cách nhau bởi khoảng trắng, chỉ số của chỉ huy trực tiếp của mỗi phần tử của tổ chức (trừ chỉ huy tối cao): số đầu tiên cho biết chỉ huy của phần tử thứ hai, số thứ hai cho biết chỉ huy của phần tử thứ ba,…

Kết quả

In ra một số nguyên duy nhất là số phần tử đối lập ít nhất cần bắt giữ.

Ví dụ

Dữ liệuKết quảMô tả
3
14
1 1 2 2 3 2 3 6 6 6 7 4 7

Hình 1
4Có thể bắt giữ 4 phần tử 6, 2, 7 và 8.

2. Gợi ý V8ORG spoj

Sử dụng thuật toán DFS.

Bởi vì tổ chức bao gồm mạng lưới thành viên và chỉ huy ở các cấp bậc khác nhau, mỗi thành viên chỉ có duy nhất một viên chỉ huy trực tiếp, và chỉ huy tối cao được đánh số 1. Ta xây dựng một đồ thị vô hướng không có chu trình. Do đó ta DFS từ 1.

Khởi tạo ds=0.

Gọi f[u] là kích thước của cây con gốc u.

Mỗi lần duyệt tới đỉnh u, khỏi tạo f[u]=1. Đỉnh u có con là v, ta sử dụng công thức quy hoạch động để cập nhật f[u]=f[u]+f[v]. Nếu f[u]>=k thì ta gán f[u]=0(cũng tức là cho cây con gốc u có kích thước bằng 0), rồi tăng ds lên 1 đơn vị.

3. Code mẫu V8ORG spoj

#include <bits/stdc++.h>

using namespace std;
    int k,n,deg[10001],low[10001],num[10001],cl[10001],
    pre[10001],f[10001],id=0,ds=0;
    vector<int> g[10001];
void dfs(int u)
{
    cl[u]=1;
    num[u]=low[u]=++id;
    f[u]=1;
    for(int i=0; i<deg[u]; i++)
    {
        int v=g[u][i];
        if(cl[v]==0)
        {
            pre[v]=u;
            dfs(v);
            f[u]+=f[v];
        }
    }
    if(f[u]>=k)
    {
        f[u]=0;
        ds++;
    }
}
int main()
{
    cin>>k>>n;
    for(int i=2; i<=n; i++)
    {
        int a;
        cin>>a;
        g[a].push_back(i);deg[a]++;
        g[i].push_back(a);deg[i]++;
    }
    dfs(1);
    cout<<ds;
}

 

 

One thought on “V8ORG spoj – Tổ chức đối lập

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *