• E. Directing Edges 解析(思維、拓樸排序)


    Codeforce 1385 E. Directing Edges 解析(思維、拓樸排序)

    今天我們來看看CF1385E
    題目連結

    題目
    給一張圖,其中有些邊一開始就是有向邊,有些邊一開始沒給定方向。求是否可能有一種邊的方向指定,能夠讓整張圖變成有向無環圖。

    前言

    完全不會......

    想法

    首先先只把固定好方向的邊放到圖上,並且跑一遍拓樸排序,我是使用每次處理入度為零的點的方法,並且用queue處理下一個要看的點的方法。
    注意到,這個方法處理的點的順序是(如果處理的圖是有向無環圖),會是深度為0的點先被處理完,然後才會是深度為1的點。。。
    如此一來,我們紀錄每個點被處理的順序。如果發現最後總編號小於(n),代表圖中有環,所以到某步以後程式找不到入度為0的點,我們即可輸出NO。
    那麼接下來我們考慮未定向的邊,觀察到,只要將邊從編號小的點連到編號大的,就一定不會有環,因為我們上面說過,編號小的深度也小。

    程式碼:

    const int _n=2e5+10;
    int t,n,m,_,cnt,num[_n],in[_n],x,y;
    bool vis[_n];
    queue<int> q;
    vector<PII> es,ans;
    VI G[_n];
    main(void) {ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
      cin>>t;while(t--){
        cin>>n>>m;rep(i,0,n+1)G[i].clear();es.clear(),ans.clear();while(!q.empty())q.pop();
        memset(num,0,sizeof(num[0])*(n+1)),cnt=0,memset(in,0,sizeof(in[0])*(n+1));
        rep(i,0,m){cin>>_>>x>>y;if(!_)es.pb({x,y});else G[x].pb(y),in[y]++,ans.pb({x,y});}
        rep(i,1,n+1)if(!in[i])q.push(i);
        while(!q.empty()){
          int now=q.front();q.pop();
          num[now]=cnt++;vis[now]=1;for(int u:G[now]){in[u]--;if(!in[u])q.push(u);}
        }if(cnt<n){cout<<"NO
    ";goto A;}
        cout<<"YES
    ";
        for(PII e:es)if(num[e.fi]<num[e.se])cout<<e.fi<<' '<<e.se<<'
    '; else cout<<e.se<<' '<<e.fi<<'
    ';
        for(PII e:ans)cout<<e.fi<<' '<<e.se<<'
    ';
        A:;
      }
      return 0;
    }
    

    標頭、模板請點Submission看
    Submission

  • 相关阅读:
    2020年JVM面试题记录
    Java对象创建过程
    Java内存模型
    JavaMail读取邮件,如何过滤需要的邮件
    Java Mail 邮件 定时收件
    Java很简单的文件上传(transferTo方式)
    Java架构师之必须掌握的10个开源工具
    Java互联网安全项目架构平台设计
    Java互联网安全项目架构设计第一篇
    Apache POI 4.0.1版本 Excel导出数据案例(兼容 xls 和 xlsx)(六)
  • 原文地址:https://www.cnblogs.com/petjelinux/p/14105770.html
Copyright © 2020-2023  润新知