zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    z470 装黑苹果 10.92
    Ubuntu 14.04安装Chromium浏览器并添加Flash插件Pepper Flash Player
    Jira 6.0.3 安装与破解
    Scrumworks乱码
    升级 CentOS git 1.7.1 到 1.7.12
    函数细说及匿名函数
    第四章—变量,作用域和内存问题(三)
    第四章—变量,作用域和内存问题(二)
    CSS-DOM的小知识(一)
    第三章——基本概念(三)
  • 原文地址:https://www.cnblogs.com/petjelinux/p/14105770.html
Copyright © 2011-2022 走看看