Please sign in first.
Official
L - 順位表/Ranking Editorial
by
L - 順位表/Ranking Editorial
by
PCTprobability
この問題では、トポロジカルソートというアルゴリズムが求められます。グラフの言葉に言い換えると、以下のようになります。
$N$ 頂点 $M$ 辺有向グラフであり、$i$ 本目の辺は頂点 $B_i$ から $A_i$ の有向辺です。トポロジカルソートをした結果の列としてあり得るもののうち、辞書順最小のものを出力してください。
この問題は、以下のように解くことが出来ます。
始め、それぞれの頂点の出次数を持った配列と集合を管理するデータ構造 \(S\) を持ちます。入次数が \(0\) である頂点を全て \(S\) に入れます。
以下を \(N\) 回繰り返します。
- \(S\) に含まれる要素のうち最小のものを取り出し、これを \(v\) とする。トポロジカルソートの結果の末尾に \(v\) を加え、\(v\) に辺が出ている頂点達の入次数を \(1\) ずつ減らし、\(0\) になったものがあれば \(S\) に追加する。
この結果得られた列が解となります。
実装例(C++)
#include <bits/stdc++.h>
using namespace std;
int main(){
int n,m;
cin>>n>>m;
set<int> s;
vector<int> d(n);
vector<vector<int>> g(n);
vector<int> ans;
for(int i=0;i<m;i++){
int a,b;
cin>>a>>b;
a--;
b--;
d[b]++;
g[a].push_back(b);
}
for(int i=0;i<n;i++) if(d[i]==0) s.insert(i);
while(s.size()){
int v=(*s.begin());
cout<<v+1<<" ";
s.erase(v);
for(auto e:g[v]){
d[e]--;
if(d[e]==0) s.insert(e);
}
}
cout<<endl;
}
posted:
last update: