重庆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步最多能经过多少格点。格点可以重复经过多次,但不重复计数。
小Q现在想知道,当棋子从格点0出发,移动N步最多能经过多少格点。格点可以重复经过多次,但不重复计数。
输入
第一行包含2个正整数V,N,其中V表示格点总数,N表示移动步数。
接下来V-1行,每行两个数Ai,Bi,表示编号为Ai,Bi的两个格点之间有连线。
V,N≤ 100, 0 ≤Ai,Bi<V
接下来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 的棋盘的主要内容,如果未能解决你的问题,请参考以下文章