一开始用的搜索,后来得40,也找不出问题,后来看题解有说用贪心写的没A
我就用贪心试了试
贪心代码:
#include<bits/stdc++.h>
using namespace std;
int n,m;
int f[310]={0,1},sum[310],b[50];//b每层的宽度,sum每个节点的子孙数
int deep[310]={0,1};//每个点的深度
int dw[50][310];//第i层,第j个点的编号
int ans=0,MMax=-1,h=-1,pp=-1;//h树的层数,MMax记录每层的节点子孙数的最大值
//pp每层的最大值的节点编号
bool vis[310];//节点i是否被感染,是 0, 否 1
vector<int> v[310];
void dfs(int g){//计算每个点的深度和子孙数
if(g!=1&&v[g].size()==1) return;
sum[g]+=v[g].size()-1;
for(int i=0;i<v[g].size();i++){
if(v[g][i]!=f[g]){
f[v[g][i]]=g;
deep[v[g][i]]=deep[g]+1;
dfs(v[g][i]);
sum[g]+=sum[v[g][i]];
}
}
}
void bdw(){//计算树的深度,每层的宽度,记录每层的节点编号
for(int i=1;i<=n;i++){
b[deep[i]]++;
dw[deep[i]][b[deep[i]]]=i;
h=max(deep[i],h);
}
}
void fans(){
for(int i=2;i<=h;i++){//遍历每一层
for(int j=1;j<=b[i];j++){//遍历每个节点
if(vis[f[dw[i][j]]]) {vis[dw[i][j]]=1;continue;}//如果父亲安全,则自己安全
if(sum[dw[i][j]]>MMax) { pp=dw[i][j]; MMax=sum[dw[i][j]]; }//打擂法找最大
}
vis[pp]=1;//切断其传播途径,安全
MMax=-1;
}
}
int main(){
cin>>n>>m;
for(int i=1,a,b;i<=m;i++){//输入
cin>>a>>b;
v[a].push_back(b);
v[b].push_back(a);
}
dfs(1);
sum[1]++;
bdw();
fans();
for(int i=2;i<=n;i++){//遍历每个节点是否安全
if(!vis[i]) ans++;//被传染,累加
}
else cout<<ans+1;//因为没计算被传染的根节点,所以加一
}
格式不好轻喷QAQ
来个DALAO帮蒟蒻解惑吧QWQ