重庆OI2017 小 Q 的棋盘

Posted mxzf0213

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了重庆OI2017 小 Q 的棋盘相关的知识,希望对你有一定的参考价值。

小 Q 的棋盘

时间限制: 1 Sec  内存限制: 512 MB

题目描述

小Q正在设计一种棋类游戏。在小Q设计的游戏中,棋子可以放在棋盘上的格点中。某些格点之间有连线,棋子只能在有连线的格点之间移动。整个棋盘上共有V个格点,编号为0,1,2…,V-1,它们是连通的,也就是说棋子从任意格点出发,总能到达所有的格点。小Q在设计棋盘时,还保证棋子从一个格点移动到另外任一格点的路径是唯一的。
小Q现在想知道,当棋子从格点0出发,移动N步最多能经过多少格点。格点可以重复经过多次,但不重复计数。

输入

第一行包含2个正整数V,N,其中V表示格点总数,N表示移动步数。
接下来V-1行,每行两个数Ai,Bi,表示编号为Ai,Bi的两个格点之间有连线。
V,N≤ 100, 0 ≤Ai,Bi<V 

输出

输出一行一个整数,表示最多经过的格点数量。

样例输入

5 2
1 0
2 1
3 2
4 3

样例输出

3

提示

从格点 0 出发移动 2 步。经过0, 1, 2这 3 个格点。

分析:树dp或贪心思路;

   贪心的话枚举某个点到0的路径上的边只走一次,其他边都走两次;

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <bitset>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <cassert>
#include <ctime>
#define rep(i,m,n) for(i=m;i<=(int)n;i++)
#define mod 1000000007
#define inf 0x3f3f3f3f
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ll long long
#define pi acos(-1.0)
#define pii pair<int,int>
#define sys system("pause")
#define ls rt<<1
#define rs rt<<1|1
#define all(x) x.begin(),x.end()
const int maxn=1e2+10;
const int N=5e2+10;
using namespace std;
ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
ll qpow(ll p,ll q,ll mo){ll f=1;while(q){if(q&1)f=f*p%mo;p=p*p%mo;q>>=1;}return f;}
int n,m,k,t,dp[2][maxn][maxn],sz[maxn],pd[2][maxn][maxn];
vi e[maxn];
void upd(int &x,int y){if(x>y)x=y;}
void dfs(int x,int y)
{
    int i;
    dp[0][x][1]=dp[1][x][1]=0;
    sz[x]=1;
    rep(i,0,e[x].size()-1)
    {
        int z=e[x][i];
        if(z==y)continue;
        dfs(z,x);
        for(int j=1;j<=sz[x];j++)
        {
            for(int k=1;k<=sz[z];k++)
            {
                upd(pd[0][x][j+k],dp[1][x][j]+dp[0][z][k]+1);
                upd(pd[0][x][j+k],dp[0][x][j]+dp[1][z][k]+2);
                upd(pd[1][x][j+k],dp[1][x][j]+dp[1][z][k]+2);
            }
        }
        for(int j=1;j<=sz[x];j++)
        {
            for(int k=1;k<=sz[z];k++)
            {
                upd(dp[0][x][j+k],pd[0][x][j+k]);
                upd(dp[1][x][j+k],pd[1][x][j+k]);
                pd[0][x][j+k]=inf;
                pd[1][x][j+k]=inf;
            }
        }
        sz[x]+=sz[z];
    }
}
int main()
{
    int i,j;
    memset(dp,inf,sizeof(dp));
    memset(pd,inf,sizeof(pd));
    scanf("%d%d",&n,&m);
    rep(i,1,n-1)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        e[x].pb(y);
        e[y].pb(x);
    }
    dfs(0,-1);
    int ret=0;
    rep(i,0,1)rep(j,1,n)
    {
        if(dp[i][0][j]<=m)ret=max(ret,j);
    }
    printf("%d\n",ret);
    return 0;
}

以上是关于重庆OI2017 小 Q 的棋盘的主要内容,如果未能解决你的问题,请参考以下文章

bzoj4813[Cqoi2017]小Q的棋盘 dfs+贪心

BZOJ [Cqoi2017] 小Q的棋盘

[CQOI2017]小Q的棋盘

解题:CQOI 2017 小Q的棋盘

BZOJ 4813: [Cqoi2017]小Q的棋盘

20191110luogu3698小Q的棋盘 | 树形背包dp | 贪心