bzoj 4813: [Cqoi2017]小Q的棋盤
阿新 • • 發佈:2018-12-12
演算法:dfs(樹型DP)+貪心
難度:NOIP
題解:
先把圖中的最長鏈找到,然後分類討論:
- 步數使得它在鏈上跑
- 跑完了全圖
- 跑完了鏈,但是跑不完全圖
鏈上的點只經過一次,消耗1步;
其它的點經過後需要返回這條鏈上,消耗2步。
程式碼如下:
#include <cstdio> #include <iostream> #include <cstring> #include <cstdlib> #include <cmath> #include <string> #include <cmath> #include <algorithm> #define ll long long #define N 105 using namespace std; struct node { int next; int to; }edge[N<<1]; int head[N],dep[N]; int cnt=1; void init() { memset(head,-1,sizeof(head)); cnt=1; } void add(int u,int v) { edge[cnt].next=head[u]; edge[cnt].to=v; head[u]=cnt++; } void dfs(int rt,int fa) { for(int i = head[rt];i != -1;i=edge[i].next) { int to=edge[i].to; if(to==fa) continue; dep[to]=dep[rt]+1; dfs(to,rt); } } int main() { int n,p; scanf("%d%d",&n,&p); init(); for(int i = 1;i < n;i++) { int a,b; scanf("%d%d",&a,&b); add(a,b),add(b,a); } dfs(0,-1); int dpp=0; for(int i = 1;i < n;i++) { dpp=max(dpp,dep[i]); } if(p<=dpp) printf("%d\n",p+1); else if(p+dpp>=(2*(n-1))/*注意,一共n-1條邊*/) printf("%d\n",n/*注意,跑完全圖後就是n個點*/); else printf("%d\n",dpp+(p-dpp)/2+1); return 0 ; }