题解:P11964 [GESP202503 七级] 图上移动
一道非常基础的二维 DP 板子题;
给出一种 DP 的做法,时间复杂度为
做法
定义
考虑状态转移,注意到
最后只需要输出整个
AC Code
#include <bits/stdc++.h>
using namespace std;
int mp[510][510],cnt[510]/*记录每个节点的邻居数量*/,f[510][21]/*同题解*/,n,m,k; // 结果数组
int main()
{
cin>>n>>m>>k;
for(int i=0;i<m;i++)
{
int u,v;
cin>>u>>v;
mp[u][cnt[u]++]=v,mp[v][cnt[v]++]=u;
}
for(int i=1;i<=n;i++) //枚举每个起点
{
bool p[510]; //滚动数组优化
memset(p,0,sizeof p);
p[i]=1;
for(int j=1;j<=k;j++)
{
bool c[510];
memset(c,0,sizeof c);
for(int u=1;u<=n;u++) //枚举上一个节点
{
if(!p[u]) continue;
for(int l=0;l<cnt[u];l++) //遍历当前节点的所有邻居
c[mp[u][l]]=1;
}
int cc=0;
for(int v=1;v<=n;v++) //看能去哪几个节点,记录
cc+=c[v],p[v]=c[v];
f[i][j]=cc;
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=k;j++) cout<<f[i][j]<<' ';
cout<<"\n";
}
}
温馨提示
考场上一开始看到的时候就给
#include<bits/stdc++.h>
using namespace std;
bool mp[510][510];
int f[510][510];
/*
f[i][j] 表示i节点下移动j步可以获得的节点数量
*/
int n,m,k,ans;
int main()
{
cin>>n>>m>>k;
for(int i=0;i<m;i++)
{
int u,v;
cin>>u>>v;
mp[u][v]=1,mp[v][u]=1;
}
for(int i=1;i<=n;i++) f[i][0]++;
for(int i=1;i<=n;i++) //当前节点
{
for(int j=1;j<=k;j++)
{
for(int r=1;r<=n;r++) //枚举可以去的点
{
if(mp[i][r]) f[i][j]+=f[r][j-1];
}
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=k;j++) cout<<f[i][j]<<' ';
cout<<"\n";
}
}