自己胡乱想的思路居然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; }