来自蒟蒻的求助,贪心90,咋回事QAQ
查看原帖
来自蒟蒻的求助,贪心90,咋回事QAQ
226844
ycw123楼主2020/8/21 11:22

一开始用的搜索,后来得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

2020/8/21 11:22
加载中...