重慶OI2017 小 Q 的棋盤
阿新 • • 發佈:2017-07-29
define print 1.0 gcd second clu urn 連通 logs
小Q現在想知道,當棋子從格點0出發,移動N步最多能經過多少格點。格點可以重復經過多次,但不重復計數。
接下來V-1行,每行兩個數Ai,Bi,表示編號為Ai,Bi的兩個格點之間有連線。
V,N≤ 100, 0 ≤Ai,Bi<V
小 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的兩個格點之間有連線。
輸出
輸出一行一個整數,表示最多經過的格點數量。樣例輸入
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++) #definemod 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 的棋盤