牛客白月赛27题解

Posted 辉小歌

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客白月赛27题解相关的知识,希望对你有一定的参考价值。

https://ac.nowcoder.com/acm/contest/6874#question

目录

巨木之森【树的直径】

#include<bits/stdc++.h> 
using namespace std;
typedef long long int LL;
const int N=1e5*4+10;
LL h[N],e[N],ne[N],w[N],idx;
LL n,m,dist[N],dist1[N],dist2[N],sum;
int ans;
void add(int a,int b,int c)

	e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;

void dfs(int u,int fa,LL d)

	dist[u]=d;
	for(int i=h[u];i!=-1;i=ne[i])
	
		int j=e[i];
		if(j==fa) continue;
		dfs(j,u,d+w[i]);
	

void dfs1(int u,int fa,LL d,LL dist[N])

	dist[u]=d;
	for(int i=h[u];i!=-1;i=ne[i])
	
		int j=e[i];
		if(j==fa) continue;
		dfs1(j,u,d+w[i],dist);
	

int main(void)

	memset(h,-1,sizeof h);
	cin>>n>>m;
	for(int i=1;i<=n-1;i++)
	
		int a,b,c; cin>>a>>b>>c;
		add(a,b,c),add(b,a,c);
		sum+=c;
	
	dfs(1,-1,0);
	LL root1=1,len1=0;
	for(int i=1;i<=n;i++) if(len1<dist[i]) len1=dist[i],root1=i;
	dfs(root1,-1,0);
	LL root2=1,len2=0;
	for(int i=1;i<=n;i++) if(len2<dist[i]) len2=dist[i],root2=i;
	dfs1(root1,-1,0,dist1);
	dfs1(root2,-1,0,dist2);
	vector<LL>ve;
	for(int i=1;i<=n;i++)
	
		LL temp=sum*2-max(dist1[i],dist2[i]);//减去最远的点
		ve.push_back(temp);
	
	sort(ve.begin(),ve.end());
	int cnt=0;
	for(int i=0;i<ve.size();i++)
		 if(ve[i]<=m) cnt++,m-=ve[i];
	cout<<cnt<<endl;
	return 0;

乐团派对【贪心 / DP】

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e6+10;
int a[N],n,maxv=0;
int main(void)
 
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i],maxv=max(maxv,a[i]);
	if(maxv>n) puts("-1");
	else
	
		sort(a+1,a+n+1);
		int cnt=0,ans=0;
		vector<int>ve;
		maxv=0;
		for(int i=1;i<=n;i++)
		
			maxv=max(maxv,a[i]);
			cnt++;
			if(cnt==maxv) ve.push_back(cnt),ans++,cnt=0,maxv=0;
		
		if(cnt<maxv)//说明最后一个不满足,那么倒着从后返回
		
			for(int i=ve.size()-1;i>=0;i--)
			
				cnt+=ve[i],ans--;
				if(cnt>=maxv) break;
			
            ans++;
		
		cout<<ans;
	
	return 0;

#include<bits/stdc++.h> 
using namespace std;
typedef long long int LL;
const int N=1e5*4+10;
int n,a[N],dp,maxv[N];
int main(void)

	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	sort(a+1,a+n+1);
	for(int i=1;i<=n;i++)
	
		if(i>=a[i]) dp=max(maxv[i-a[i]]+1,dp);
		else dp=0;
		maxv[i]=max(maxv[i-1],dp);
	
	if(dp==0)  puts("-1");
	else cout<<dp;
	return 0;

光玉小镇【状压DP TSP】

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=210;
LL f[1<<17][17],dist[25][25],n,m,t;
vector< pair<int,int> >ve;
int st[N][N];
int dx[4]=-1,0,0,1;
int dy[4]=0,-1,1,0;
char c[N][N];
void bfs(int x,int y)

	st[x][y]=0;
	queue<pair<int,int>>q; q.push(x,y);
	while(q.size())
	
		auto temp=q.front(); q.pop();
		x=temp.first,y=temp.second;
		for(int i=0;i<4;i++)
		
			int tempx=x+dx[i],tempy=y+dy[i];
			if(tempx<=0||tempx>n||tempy<=0||tempy>m) continue;
			if(st[tempx][tempy]!=-1) continue;
			if(c[tempx][tempy]=='#') continue;
			st[tempx][tempy]=st[x][y]+1;
			q.push(tempx,tempy);
		
	

int main(void)

	memset(dist,0x3f,sizeof dist);
	cin>>n>>m>>t;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			cin>>c[i][j];
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			if(c[i][j]=='S') ve.push_back(i,j);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			if(c[i][j]=='T') ve.push_back(i,j);
    bool flag=0;
	for(int i=0;i<ve.size();i++)
	
		memset(st,-1,sizeof st);
		bfs(ve[i].first,ve[i].second);
		for(int j=0;j<ve.size();j++) 
		
			int x=ve[j].first,y=ve[j].second;
            if(st[x][y]==-1) flag=1;//不可达
			dist[i][j]=st[x][y];
		
	
	memset(f,0x3f,sizeof f);
	f[1][0]=0;
	LL cnt=ve.size();
	for(int i=0;i<(1<<cnt);i++)
	
		for(int j=0;j<cnt;j++)
		
			if(i>>j&1)
			
				for(int k=0;k<cnt;k++)
				
					int temp=i-(1<<j);
					if(temp>>k&1) f[i][j]=min(f[i][j],f[i-(1<<j)][k]+dist[k][j]);
				
			
		
	
	LL ans=0x3f3f3f3f;
	for(int i=1;i<cnt;i++) ans=min(ans,f[(1<<cnt)-1][i]+dist[i][0]);
    if(flag) puts("-1");
	else cout<<ans+t*(cnt-1);
	return 0;

巅峰对决【线段树】

#include<bits/stdc++.h>
using namespace std;
const int N=1e5*2+10;
struct node

	int l,r,minv,maxv;
tr[N*4];
int n,m,w[N];
void build(int u,int l,int r)//建树

    tr[u]=l,r;
    if(l==r) return;
    int mid=tr[u].l+tr[u].r>>1;
    build(u*2,l,mid);
    build(u*2+1,mid+1,r);

void pushup(int u)

    tr[u].maxv=max(tr[u*2].maxv,tr[u*2+1].maxv);
    tr[u].minv=min(tr[u*2].minv,tr[u*2+1].minv);

node query(int u,int l,int r)

    if(tr[u].l>=l&&tr[u].r<=r) return tr[u];//包含
    else
    
        int mid=(tr[u].l+tr[u].r)/2;
        int maxv=0,minv=1e9;
        if(l<=mid)
		
			node temp=query(u*2,l,r);
		 	maxv=max(maxv,temp.maxv);//左边有交集
		 	minv=min(minv,temp牛客白月赛8题解

牛客白月赛4 题解

牛客白月赛11题解

牛客白月赛12题解

牛客白月赛10题解

牛客白月赛14题解