P11964 [GESP202503 七级] 图上移动
题目
思路
参考了洛谷的第一篇题解
简单做法
我们发现只要遍历每个k和每个点即可,然后对每个点和k做dfs,用集合set去重即可
#include<bits/stdc++.h>
using namespace std;
int n,m,k,mb;
set<int>s;
vector<int>v[505];
void dfs(int x,int now){
if(now==mb){
s.insert(x);
return;
}
for(int i=0;i<v[x].size();i++){
int u=v[x][i];
dfs(u,now+1);
}
}
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
cin>>n>>m>>k;
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
v[x].push_back(y);
v[y].push_back(x);
}
for(int i=1;i<=n;i++){
for(int j=1;j<=k;j++){
s.clear();
mb=j;
dfs(i,0);
cout<<s.size()<<' ';
}
cout<<'\n';
}
return 0;
}
但是这种做法会超时,时间复杂度达到了o(nk(n^k)),只能得20分
提交记录
如何优化?
我们可以给每个点都定义一个状态,定义vis[i][j]为走到i点时用了j步。
然后dfs,如果走过就直接返回,否则就遍历与他相邻的边。
代码
有注释
#include<bits/stdc++.h>
using namespace std;
int n,m,k,mb;
int vis[505][25];
vector<int>v[505];
void dfs(int x,int step){
if(vis[x][step])return;//走过了
vis[x][step]=1;//标记
if(step>=k)return;//边界
for(int i=0;i<v[x].size();i++){
int u=v[x][i];
dfs(u,step+1);
}
}
int main(){
std::ios::sync_with_stdio(false);//关闭输入输出流
std::cin.tie(0);
std::cout.tie(0);
cin>>n>>m>>k;
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
v[x].push_back(y);
v[y].push_back(x);
}
for(int i=1;i<=n;i++){
dfs(i,0);//dfs
for(int j=1;j<=k;j++){
int ans=0;
for(int i1=1;i1<=n;i1++){
ans+=vis[i1][j];//统计
}
cout<<ans<<' ';
}
cout<<'\n';
for(int j=1;j<=k;j++){
for(int i1=1;i1<=n;i1++){
vis[i1][j]=0;//初始化
}
}
}
return 0;
}
无注释
#include<bits/stdc++.h>
using namespace std;
int n,m,k,mb;
int vis[505][25];
vector<int>v[505];
void dfs(int x,int step){
if(vis[x][step])return;
vis[x][step]=1;
if(step>=k)return;
for(int i=0;i<v[x].size();i++){
int u=v[x][i];
dfs(u,step+1);
}
}
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
cin>>n>>m>>k;
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
v[x].push_back(y);
v[y].push_back(x);
}
for(int i=1;i<=n;i++){
dfs(i,0);
for(int j=1;j<=k;j++){
int ans=0;
for(int i1=1;i1<=n;i1++){
ans+=vis[i1][j];
}
cout<<ans<<' ';
}
cout<<'\n';
for(int j=1;j<=k;j++){
for(int i1=1;i1<=n;i1++){
vis[i1][j]=0;
}
}
}
return 0;
}

浙公网安备 33010602011771号