Skip to content
Logic Formatting

Logic Formatting

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

Posted on 2025 年 1 月 12 日 By jeff

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\n";goto A;}  
    cout<<"YES\n";  
    for(PII e:es)if(num[e.fi]<num[e.se])cout<<e.fi<<' '<<e.se<<'\n'; else cout<<e.se<<' '<<e.fi<<'\n';  
    for(PII e:ans)cout<<e.fi<<' '<<e.se<<'\n';  
    A:;  
  }  
  return 0;  
}  

標頭、模板請點Submission看
Submission

ojcode codeforceojcode思維拓樸排序

文章導覽

Previous post
Next post

發佈留言 取消回覆

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

近期文章

  • B. Kyoya and Permutation 解析(思維、數論、DP)
  • G. Guess One Character 解析(思維)
  • E. The Road to Berland is Paved With Good Intentions 解析(思維、2-SAT、SCC、拓樸排序)
  • E. Xor-sequences 解析(思維、矩陣快速冪)
  • LeetCode. First Missing Positive 解析(思維)

近期留言

尚無留言可供顯示。

彙整

  • 2025 年 2 月
  • 2025 年 1 月

分類

  • ojcode
©2026 Logic Formatting | WordPress Theme by SuperbThemes