洛谷 P3916 【图的遍历】
2024-10-09 05:51:02
这道题绿题有点高了吧...
我一开始的思路就是一个暴力的遍历,用递归加一个记忆化,对于一个点不断的往下搜索,然后确定最大的,返回,给上面的节点。就在这个过程中,我们是搜到最大的数然后返回给上层的数,那我们为什么不直接从大的出发,那么大的那个数到达的点也就必然能达到这个大的数,这个很好实现,直接反向建图,从大开始遍历,遍历到达的点ans值直接就为这个数。这样,我写下了我的第一代程序,超时了,八十分。
#include <bits/stdc++.h>
using namespace std;
int n , m;
int ans[100010] , vis[100010];
vector<int> e[100010];
void dfs(int k , int step){
if(vis[step] || ans[step] >= k) return;
vis[step] = 1;
if(!ans[step] || ans[step] < k) ans[step] = k;
for(int i = 0; i < e[step].size(); i++) dfs(k , e[step][i]);
}
int main(){
cin >> n >> m;
for(int i = 1; i <= m; i++){
int x , y;
cin >> x >> y;
e[y].push_back(x);
}
for(int i = n; i >= 1; i--){
memset(vis , 0 , sizeof(vis));
dfs(i , i);
}
for(int i = 1; i <= n; i++) cout << ans[i] << " ";
return 0;
}
为什么会超时呢,注意到,我们是从大的开始跑的,从大到小枚举,那么这个数之前就被遍历过了的话,现在再次遍历到时,一定是小于之前遍历时保存的数,这样,就可以写下最终的代码:
#include <bits/stdc++.h>
using namespace std;
int n , m;
int ans[100010] , vis[100010];
vector<int> e[100010];
void dfs(int k , int step){
if(vis[step]) return;
vis[step] = 1;
ans[step] = k;
for(int i = 0; i < e[step].size(); i++) dfs(k , e[step][i]);
}
int main(){
cin >> n >> m;
for(int i = 1; i <= m; i++){
int x , y;
cin >> x >> y;
e[y].push_back(x);
}
for(int i = n; i >= 1; i--) dfs(i , i);
for(int i = 1; i <= n; i++) cout << ans[i] << " ";
return 0;
}
最新文章
- 学习微信小程序之css2
- js中的call和apply
- hdu4750Count The Pairs(最小生成树找瓶颈边)
- paip.汉字简化大法总结
- Powerdesigner自定义DBMS(以derby数据库为例)
- vim功能使用
- Ksoap2 获取webservice返回值的getResponse() 出现的问题
- SpringAOP 基础具体解释
- C++ Socket超时设置
- Android selector item 属性大全(按钮按下不同效果)
- 首发Zend Studio 10.6正式版注册破解(2014-02-06更新)
- 《how to design programs》14章 再论自引用数据
- PHP遍历文件夹下的文件和获取到input name的值
- 一步一步学python(五) -条件 循环和其他语句
- 【Access2007】将Excel表导入到Access2007在现有的表成
- Promise的用法
- Java语法细节 - 可见性
- Python 基础API
- ArcGIS 卷帘效果
- 平均数_中位数_众数在SqlServer实现