题意:给定n,s,k,分别表示树有n个结点,服务器位于s结点,只要客服端(叶节点为客户端)不超过服务器k距离,则都可以覆盖,问最少需要布置多少个服务器能够覆盖全部客户端
思路:1:将无根树转为有根树,并将每层的叶节点关系保存
2:从第n-1个叶结点开始查找它的k级祖先,放置服务器在k级祖先处,并将距离k级祖先小于k距离的所有叶节点覆盖(方便下一次查找跳过)
结:第一次用c++的vector写题,不知道为啥用结构体进行模拟就是错的。
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
using namespace std;
const int maxn = 1010;
int fa[maxn],cover[maxn];
vector<int>node[maxn];
vector<int>gr[maxn];
int n,s,k;
void dfs(int u,int f,int d)//将无根树转为以s为根的有根树
{
int i,v,l;
fa[u] = f;
l = gr[u].size();
if(l == 1&&d > k)
node[d].push_back(u);//叶节点即客户端存入node
for(i = 0; i < l; i ++)
{
v = gr[u][i];
if(v!=f)
dfs(v,u,d+1);
}
return;
}
void dfs2(int u,int f,int d)
{
int i,v;
cover[u] = 1;//已被服务器覆盖则标记为1
for(i = 0; i < gr[u].size(); i ++)
{
v = gr[u][i];
if(v!=f&&d < k)//覆盖在k范围内的叶节点
dfs2(v,u,d+1);
}
return;
}
int find()
{
int i,j,v,ans = 0,l,u,m;
for(i = n-1; i > k; i--)
{
l = node[i].size();
for(j = 0; j < l; j ++)
{
v = node[i][j];
if(cover[v])//如果叶节点即客户端已经被覆盖过,则跳过
continue;
u = v;
for(m = 0; m < k; m ++)//找到u的k级祖先
u = fa[u];
dfs2(u,-1,0);
ans ++;//记录布置服务器的个数
}
}
return ans;
}
int main()
{
int t,i,j,a,b;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
scanf("%d%d",&s,&k);
memset(fa,0,sizeof(fa));
memset(cover,0,sizeof(cover));
for(i = 0; i <= n; i ++)
{
node[i].clear();
gr[i].clear();
}
for(i = 0; i < n-1; i ++)
{
scanf("%d%d",&a,&b);
gr[a].push_back(b);
gr[b].push_back(a);
}
dfs(s,-1,0);
printf("%d\n",find());
}
return 0;
}
结构体实现,错了。。。
#include<stdio.h>
#include<cstdio>
#include<string.h>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 2010;
int n,s,k,ans;
int df[maxn],cover[maxn];
struct node{
int num[maxn];
int l;
}grd[maxn],node[maxn];
void dfs(int u,int f,int d)
{
df[u] = f;
int L = grd[u].l ;
if(L == 1&&d > k)
{
int l2 = node[u].l ;
node[d].num[l2] = u;
node[u].l ++;
}
for(int i = 0; i < L; i ++)
{
int v = grd[u].num[i];
if(v != f)
dfs(v,u,d+1);
}
return;
}
void dfs2(int u,int f,int d)
{
cover[u] = 1;
for(int i = 0; i < grd[u].l ; i ++)
{
int v = grd[u].num[i];
if(v !=f &&d < k)
dfs2(v,u,d+1);
}
return;
}
void find()
{
ans = 0;
for(int i = n-1; i > k; i--)
{
int L = node[i].l ;
for(int j = 0; j < L; j ++)
{
int u = node[i].num[j];
if(cover[u])
continue;
int v = u;
for(int x = 0; x < k; x ++)
v = df[v];
dfs2(v,-1,0);
ans ++;
}
}
return;
}
int main()
{
int t,a,b;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
scanf("%d%d",&s,&k);
memset(grd,0,sizeof(grd));
memset(node,0,sizeof(node));
for(int i = 0; i < n-1; i ++)
{
scanf("%d%d",&a,&b);
int L = grd[a].l ;
int L2 = grd[b].l ;
grd[a].num[L] = b;
grd[a].l ++;
grd[b].num[L2] = a;
grd[b].l ++;
}
memset(df,0,sizeof(df));
memset(cover,0,sizeof(cover));
dfs(s,-1,0);
find();
printf("%d\n",ans);
}
return 0;
}