专栏文章
题解:P11964 [GESP202503 七级] 图上移动
P11964题解参与者 3已保存评论 2
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @mipt2q8m
- 此快照首次捕获于
- 2025/12/03 17:29 3 个月前
- 此快照最后确认于
- 2025/12/03 17:29 3 个月前
一道非常基础的二维 DP 板子题;
给出一种 DP 的做法,时间复杂度为 。
做法
定义 表示第 个节点走了 步后可以到达的节点数;
考虑状态转移,注意到 不论任何情况都等于 1 即任意情况下走 0 步可以到达的节点数只有它自己本身;枚举每个节点可以到达的节点进行叠加就可以推出转移方程了:
最后只需要输出整个 数组即可。
AC Code
CPP#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";
}
}
温馨提示
考场上一开始看到的时候就给 的状态搞错了,搞成了记录每个节点的路径数,特此告诫后人:
CPP#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";
}
}
相关推荐
评论
共 2 条评论,欢迎与作者交流。
正在加载评论...