洛谷P5021 赛道修建

话说去年为什么暴力炸成了15......

其实我现在都不会做,参考的一位P党大佬的题解,写成了C++版而已(附注了一些关键部分的细节)。

总之现在弄懂了QWQ

代码:

#include
using namespace std;

const int maxn=1e6+10,maxm=2e6+10,inf=1e8;
int bg[maxn],nt[maxm],to[maxm],w[maxm],e;
int n,m,ed[maxn],num,st[maxn],top,cnt,up[maxn],ans;

void insert(int x,int y,int z) {
	nt[++e]=bg[x];
	to[e]=y;
	w[e]=z;
	bg[x]=e;
}

void dfs(int x,int fa,int lim) {
	int i,j,u;
	up[x]=0;
	for (i=bg[x];i;i=nt[i]) {
		u=to[i];
		if (u==fa) continue;
		dfs(u,x,lim);
	}
	num=0;
	for (i=bg[x];i;i=nt[i]) {
		u=to[i];
		if (u==fa) continue; //PS:一顿苦调代码,结果好久才发现是这句话忘写了QAQ
		ed[++num]=w[i]+up[u]; //每条边继承子节点的上传值
	}
	//贪心:
	sort(ed+1,ed+num+1); //排完序使得边满足单调性
	i=1; j=num; top=0; 
	while (ed[j]>=lim) { //假如大边可以自己(连带其子节点的上传值,之后省略这句话)成为一条赛道
		j--;
		cnt++;
	}
	while (i<=j) {
		while (ed[i]+ed[j]>=lim && i=m;
}

int main() {
	int i,x,y,z,l=inf,r=0,mid;
	scanf("%d%d",&n,&m);
	for (i=1;i

 

你可能感兴趣的:(刷题)