zoukankan      html  css  js  c++  java
  • 【CQOI2017】【BZOJ4813】小Q的棋盘 DFS

    题目描述

      有一棵树,你要从(0)号点开始走,你可以走(m)步,问你最多能经过多少个不同的点。

      (nleq 100)

    题解

      出题人的做法是DP(一个简单的树形DP),但是可以直接通过一次DFS做出来。

      先DFS整棵树,设(d)为所有点深度的最大值。

      若(m<d),那么显然走这条最长的链是最优的,答案为(m+1)

      否则我们可以先沿着这条链走到底,在这个过程中可以往其他的子树走,每花两步可以走到一个新的点,答案为(min(n,d+lfloorfrac{m-d+1}{2} floor))

      时间复杂度:(O(n))

    代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    #include<ctime>
    #include<utility>
    #include<cmath>
    #include<functional>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> pii;
    typedef pair<ll,ll> pll;
    void sort(int &a,int &b)
    {
    	if(a>b)
    		swap(a,b);
    }
    void open(const char *s)
    {
    #ifndef ONLINE_JUDGE
    	char str[100];
    	sprintf(str,"%s.in",s);
    	freopen(str,"r",stdin);
    	sprintf(str,"%s.out",s);
    	freopen(str,"w",stdout);
    #endif
    }
    int rd()
    {
    	int s=0,c;
    	while((c=getchar())<'0'||c>'9');
    	do
    	{
    		s=s*10+c-'0';
    	}
    	while((c=getchar())>='0'&&c<='9');
    	return s;
    }
    void put(int x)
    {
    	if(!x)
    	{
    		putchar('0');
    		return;
    	}
    	static int c[20];
    	int t=0;
    	while(x)
    	{
    		c[++t]=x%10;
    		x/=10;
    	}
    	while(t)
    		putchar(c[t--]+'0');
    }
    int upmin(int &a,int b)
    {
    	if(b<a)
    	{
    		a=b;
    		return 1;
    	}
    	return 0;
    }
    int upmax(int &a,int b)
    {
    	if(b>a)
    	{
    		a=b;
    		return 1;
    	}
    	return 0;
    }
    int maxd;
    vector<int> g[110];
    void dfs(int x,int fa,int dep)
    {
    	maxd=max(maxd,dep);
    	for(auto v:g[x])
    		if(v!=fa)
    			dfs(v,x,dep+1);
    }
    int main()
    {
    	open("chessbord");
    	int n,m;
    	scanf("%d%d",&n,&m);
    	int x,y;
    	for(int i=1;i<n;i++)
    	{
    		scanf("%d%d",&x,&y);
    		x++;
    		y++;
    		g[x].push_back(y);
    		g[y].push_back(x);
    	}
    	dfs(1,0,1);
    	int ans;
    	if(m<maxd)
    		ans=m+1;
    	else
    		ans=min(n,maxd+(m-maxd+1)/2);
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    反射
    IDEA配置数据库
    配置idea的maven镜像为aliyun
    蓝桥---芯片测试(思维)
    汉诺塔(思维、DP思想)
    立方数(质因子、优化)
    碎碎念(DP)
    牛牛战队的比赛地(三分)
    子段乘积(尺取、逆元)
    子段异或(位运算)
  • 原文地址:https://www.cnblogs.com/ywwyww/p/8909555.html
Copyright © 2011-2022 走看看