题目描述
有N个顶点,在顶点上放置信号塔则与之相邻的顶点能被信号覆盖到。
现在给你N-1条边,求解最少需要放置多少个信号塔才能使得所有顶点都有信号
输入
第一行:一个整数N
接下来N-1行:每行两个整数a和b(中间空格隔开)
输出
一个整数,最少需要放置信号塔的个数
样例输入
7
1 2
2 3
2 5
2 7
3 4
5 6
样例输出
3
这该死的信号塔终于有点思路了了了
但还是不过,希望路过的dl看看,留下点思路给我这小菜鸡
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e3+5;
int mp[maxn][maxn];
int f[maxn],dp[maxn];
int vit[maxn];
int n;
void dfs(int u)
{
vit[u]=1;
for(int i=1;i<=n;i++){
if(mp[u][i]&&!vit[i])
vit[i]=1;
}
vit[f[u]]=1; //父顶点的父顶点也要标记
return;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n-1;i++){
int a,b;
scanf("%d%d",&a,&b);
if(a>b)swap(a,b); //因为为无向图,所以可以把a>b的情况变为a<b(将无根树变为以1为根的有根树)
mp[a][b]=1;
f[b]=a; //记录这条边是由a->b的,即顶点b的前顶点(父顶点)是a
}
for(int i=1;i<=n;i++){
dp[i]=dp[f[i]]+1; //统计各个顶点的深度
//(这里需要注意的是那个边的情况只能为(a<b),如果有a>b的情况,二个for循环可以解决问题)因为上面交换了大小,所以就不需要
}
int ans=0;
while(1){
int p=0;
for(int i=1;i<=n;i++){
if(!vit[i]&&dp[i]>dp[p]){ //从最深的顶点开始遍历,才能保证信号塔数目最少
p=i;
}
}
if(p==0)break; //顶点都遍历完了,跳出循环
vit[p]=1; //标记已遍历过
dfs(f[p]); //拿父顶点继续遍历,将与父顶点所连接的顶点全部标记
ans++; //信号塔数目加1
}
printf("%d\n",ans);
return 0;
}
最后感谢王盈钦dl的提醒,然我不在自闭了。。。。。。。