BZOJ4813: [Cqoi2017]小Q的棋盘
【传送门:BZOJ4813】
简要题意:
给出一棵树,从根节点出发,走n步,求最多能经过多少个点(重复经过不算)
题解:
贪心
本来想着树形DP,太麻烦了,懒得码
首先我们把最长链留到最后走,这样子我们就可以一次性将最长链走完了,那么最长链的每条边的代价就是1
而其它边的代价就为2(因为要往回走),然后贪心就好了
特殊情况:
1.最长链的长度>=步数,直接输出步数
2.步数足够将整张图走完,直接输出n
直接在贪心的时候顺便处理就好了
参考代码:
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<cstdlib> using namespace std; struct node { int x,y,next; }a[210];int len,last[110]; void ins(int x,int y) { len++; a[len].x=x;a[len].y=y; a[len].next=last[x];last[x]=len; } int dep[110]; void dfs(int x,int fa) { for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(y!=fa) { dfs(y,x); dep[x]=max(dep[y]+1,dep[x]); } } } int main() { int v,n; scanf("%d%d",&v,&n); len=0;memset(last,0,sizeof(last)); for(int i=1;i<v;i++) { int x,y; scanf("%d%d",&x,&y); x++;y++; ins(x,y);ins(y,x); } memset(dep,0,sizeof(dep)); dfs(1,1); int ans=min(dep[1],n)+1; n-=ans-1; while(ans<v&&n>=2){ans++;n-=2;} printf("%d\n",ans); return 0; }
渺渺时空,茫茫人海,与君相遇,幸甚幸甚