题目中好像说有这么一句话:
牧场运输系统可以被构建成一棵以 1 号节点为根的树。
所以我直接见无向边,跑以1为根的DFS,代码见下:
#include<iostream>
#include<vector>
#include<cstring>
using namespace std;
const int N=155;
vector<int> G[N<<1];
int n,p,dp[N][N],size[N],ind[N],ans=0x3f3f3f3f;
void dfs(int u,int fa)
{
size[u]=1;
dp[u][1]=G[u].size();
for(int v:G[u])
{
if(v==fa) continue;
dfs(v,u);
size[u]+=size[v];
for(int j=min(size[u],p);j>=0;j--)
for(int k=1;k<j;k++)
dp[u][j]=min(dp[u][j],dp[u][j-k]+dp[v][k]-1);
}
if(u!=1) ans=min(ans,dp[u][p]+1);
else ans=min(ans,dp[u][p]);
}
int main()
{
cin>>n>>p;
for(int i=1,a,b;i<n;i++)
{
cin>>a>>b;
G[a].push_back(b);
G[b].push_back(a);
}
memset(dp,0x3f,sizeof(dp));
dfs(1,0);
cout<<ans<<endl;
return 0;
}
很不幸,样例都没过(疑惑) 后来想了想,又改成有向边,用入度找根,代码如下:
#include<iostream>
#include<vector>
#include<cstring>
using namespace std;
const int N=155;
vector<int> G[N<<1];
int n,p,dp[N][N],size[N],ind[N],root,ans=0x3f3f3f3f;
void dfs(int u)
{
size[u]=1;
dp[u][1]=G[u].size();
for(int v:G[u])
{
dfs(v);
size[u]+=size[v];
for(int j=min(size[u],p);j>=0;j--)
for(int k=1;k<j;k++)
dp[u][j]=min(dp[u][j],dp[u][j-k]+dp[v][k]-1);
}
if(u!=root) ans=min(ans,dp[u][p]+1);
else ans=min(ans,dp[u][p]);
}
int main()
{
cin>>n>>p;
for(int i=1,a,b;i<n;i++)
{
cin>>a>>b;
G[a].push_back(b);
//G[b].push_back(a);
ind[b]++;
}
for(int i=1;i<=n;i++)
if(!ind[i]) {root=i;break;}
memset(dp,0x3f,sizeof(dp));
dfs(root);
cout<<ans<<endl;
return 0;
}
结果就AC了。 我搞不懂这是什么迷惑操作,烦请各路神犇答疑解惑(抱拳)(鲜花)