• 【算法每日一练]-图论(保姆级教程 篇3(遍历))#图的遍历 #奶牛牧场 #杂务


    今天讲图的遍历

    目录

    题目:图的遍历

    思路:

    题目:奶牛牧场

    思路:  

    题目:杂务

    思路:


            

    题目:图的遍历

            

    思路:

             

    正向建边需要跑O(N^2)会超时,所以反向建边,先从最大的点出发,能到的所有点都是最大点的值,然后更新下一个没有被更新过的点,
    这样只需要O(n)就行,而且因为是从大到小遍历每个点,这样以来,每个点第一个更新的值便是最大值

            

    1. #include
    2. #define N 100005
    3. using namespace std;
    4. int n,m,a[N];
    5. vector <int>p[N];
    6. void dfs(int x,int v){//从v点出发,可以到x点
    7. a[x]=v; //所以这个x点能到的最大点就是v
    8. for(int i=0;isize();i++){
    9. if(!a[p[x][i]]) dfs(p[x][i],v);//如果这个p[x][i]点没有更新过,就用当前点的值进行更新
    10. }
    11. }
    12. int main(){
    13. cin>>n>>m;int u,v;
    14. for(int i=1;i<=m;i++){
    15. cin>>u>>v;
    16. p[v].push_back(u);//反向建边,箭头都逆向一下
    17. }
    18. for(int i=n;i>=0;i--){
    19. if(a[i]==0) dfs(i,i);//每个点都出发进行更新,被更新过的点不能再更新,否则一定会变小
    20. }
    21. for(int i=1;i<=n;i++){
    22. cout<' ';
    23. }
    24. return 0;
    25. }

            

            

    题目:奶牛牧场

            

    思路:

    不要奇怪,我写了bfs和dfs两种遍历方法,哪个都行

    1. #include
    2. using namespace std;
    3. const int K=105,N=1005;
    4. int k,n,m,ans;
    5. int a[K],cnt[N],vis[N];//cnt是能到此点的起点个数
    6. vector<int>ve[N];
    7. void dfs(int u){
    8. if(vis[u])return ;
    9. cnt[u]++;vis[u]=1;
    10. for(int i=0,sz=ve[u].size();i
    11. if(vis[ve[u][i]])continue;//注意这里是v[][]
    12. dfs(ve[u][i]);//个人认为vis=1放这里也可以
    13. }
    14. }
    15. void bfs(int u);
    16. int main(){
    17. cin>>k>>n>>m;int x,y;
    18. for(int i=1;i<=k;i++)cin>>a[i];//保存每个奶牛的位置
    19. for(int i=1;i<=m;i++){
    20. scanf("%d%d",&x,&y);
    21. ve[x].push_back(y);
    22. }
    23. for(int i=1;i<=k;i++){
    24. memset(vis,0,sizeof(vis));
    25. // dfs(a[i]);
    26. bfs(a[i]);
    27. }
    28. for(int i=1;i<=n;i++) if(cnt[i]==k)ans++;
    29. cout<
    30. }
    31. void bfs(int u){
    32. queue<int>q;
    33. q.push(u);
    34. while(!q.empty()){
    35. int cur=q.front();q.pop();
    36. if(vis[cur])continue;
    37. vis[cur]=1;cnt[cur]++;
    38. for(int i=0,sz=ve[cur].size();i
    39. int v=ve[cur][i];
    40. if(vis[v])continue;
    41. q.push(v);
    42. }
    43. }
    44. }

            

            

    题目:杂务

            

    思路:

             

    注意到前驱任务可以并发执行,所以我们只需要完成最长前驱就行

    直接topo排序就行,不过这里提供一种dfs的topo排序

    vis[x]=max(vis[x],dfs(v[x][i])+tim[x]); 其实在树形dp的时候就已经见过一面的

            

    1. #include
    2. #define N 10010
    3. using namespace std;
    4. vector <int> v[N];
    5. int n,ans,tim[N],vis[N];//vis[x]存放完成任务x所需要的时间
    6. int dfs(int x){
    7. if(vis[x]) return vis[x]; //枝剪
    8. for(int i=0;isize();i++){
    9. vis[x]=max(vis[x],dfs(v[x][i])+tim[x]);//递推公式
    10. }
    11. return vis[x];
    12. }
    13. int main(){
    14. cin>>n;int x,y;
    15. for(int i=1;i<=n;i++){
    16. cin>>x>>tim[x];//输入x,耗时tim[x]
    17. while(cin>>y&&y!=0){
    18. v[x].push_back(y);//正向建边,x的准备工作为y
    19. }
    20. if(v[x].size()==0)vis[x]=tim[x];
    21. }
    22. for(int i=1;i<=n;i++){
    23. ans=max(ans,dfs(i)); //因为没有关系的两个任务可以并发执行
    24. }
    25. cout<
    26. }

  • 相关阅读:
    kubeadm快速部署K8S
    ScaleFlux CSD 2000 在携程的应用实践
    【CMAKE极简教程】不断更新中......
    VINS系统框架--原理剖析
    Springboot毕设项目旅游助手系统wp1hv(java+VUE+Mybatis+Maven+Mysql)
    【Proteus仿真】【STM32单片机】多功能智能台灯
    java线程调度
    SpringCloud整合分布式事务Seata 1.4.1 支持微服务全局异常拦截
    (仿牛客社区项目)Java开发笔记7.6:热帖排行
    [入门到吐槽系列] Webix 10分钟入门 一 管理后台制作
  • 原文地址:https://blog.csdn.net/m0_69478376/article/details/134358310