UVa:1267 Network

自己胡乱想的思路居然AC了,真是泪流满脸啊。。

首先要无根树化为有根树,这个刘汝佳第一本书上有。然后dfs取所有叶结点,并按照其深度从大到小排序。这样依次判断每个叶结点,首先对于该叶结点访问与它距离k以内的所有结点看是否为服务器,如果没有则要从该叶结点往上沿着父亲结点遍历,选距离k的那个结点放置服务器。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <algorithm>
#define ll long long
#define INF 2139062143
#define inf -2139062144
#define MOD 20071027
#define MAXN 1005
using namespace std;
struct Tree
{
    int father;
    vector<int> child;
};
struct Node
{
    int num,deep;
};
vector<Node> vec;
int n,k,s;
Tree tree[MAXN];
bool flag[MAXN],vis[MAXN];
bool gl[MAXN][MAXN],leave[MAXN];
int ans;
void Init()
{
    for(int i=0; i<=n; ++i)
    {
        tree[i].child.clear();
        tree[i].father=0;
    }
    vec.clear();
    memset(gl,0,sizeof(gl));
    memset(leave,0,sizeof(leave));
}
void getnode(int u,int d)
{
    if(tree[u].child.size()==0)
    {
        vec.push_back(Node {u,d});
        leave[u]=true;
    }
    else
    {
        for(int i=0; i<tree[u].child.size(); ++i)
            getnode(tree[u].child[i],d+1);
    }
}
bool search(int u,int d)
{
    if(d<=k)
    {
        vis[u]=true;
        if(flag[u]) return true;
        for(int i=0; i<tree[u].child.size(); ++i)
            if(!vis[tree[u].child[i]]&&search(tree[u].child[i],d+1)) return true;
        if(!vis[tree[u].father]&&search(tree[u].father,d+1)) return true;
        return false;
    }
    return false;
}
bool makeflag(int u,int d)
{
    if(d<=k)
    {
        if(d==k)
        {
            flag[u]=true;
            return true;
        }
        if(makeflag(tree[u].father,d+1)) return true;
        return false;
    }
    return false;
}
bool cmp(Node a,Node b)
{
    return a.deep>b.deep;
}

void maketree(int u,int f)
{
    tree[u].father=f;
    for(int i=1; i<=n; ++i)
        if(gl[u][i]&&i!=f)
        {
            tree[u].child.push_back(i);
            maketree(i,u);
        }
}
int main()
{
    int T;
    //freopen("asdf.txt","w",stdout);
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        scanf("%d%d",&s,&k);
        Init();
        for(int i=1; i<n; ++i)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            gl[x][y]=gl[y][x]=true;
        }
        maketree(s,-1);
        ans=0;
        getnode(s,0);
        sort(vec.begin(),vec.end(),cmp);
        memset(flag,0,sizeof(flag));
        flag[s]=true;
        for(int i=0; i<vec.size(); ++i)
        {
            memset(vis,0,sizeof(vis));
            if(!search(vec[i].num,0))
            {
                makeflag(vec[i].num,0);
                ans++;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}


 

你可能感兴趣的:(UVa:1267 Network)