牛客白月赛27题解
Posted 辉小歌
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客白月赛27题解相关的知识,希望对你有一定的参考价值。
https://ac.nowcoder.com/acm/contest/6874#question
目录
- 巨木之森【树的直径】
- 乐团派对【贪心 / DP】
- 光玉小镇【状压DP TSP】
- 巅峰对决【线段树】
- 使徒袭来【二分】
- 核弹剑仙【dfs / 拓扑】
- 虚空之力【贪心】
- 社团游戏【前缀和】
- 名作之壁【单调栈】
- 逃跑路线【思维】
巨木之森【树的直径】
#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题解