質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

667閲覧

トポロジカルソートを用いた競技プログラミングの問題

退会済みユーザー

退会済みユーザー

総合スコア0

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2018/07/12 10:58

現状

トポロジカルソートと呼ばれるアルゴリズムを用いて解くことのできるこの問題(https://beta.atcoder.jp/contests/tenka1-2016-quala/tasks/tenka1_2016_qualA_c)に取り組んでいるのですが行き詰まってしまいました。

発生している問題・エラーメッセージ

次の1つ目のリンクから飛んで頂いてわかるようにいくつかのテストケース(非公開)に正解できていません。また必要でしたらトポロジカルソートの概要は2つ目のリンクからご覧になれます。自分が用いたのはKahn's algorithmと呼ばれるものです。 https://beta.atcoder.jp/contests/tenka1-2016-quala/submissions/2830453 https://ja.m.wikipedia.org/wiki/トポロジカルソート

該当のソースコード

c++

1#include <bits/stdc++.h> 2 3using namespace std; 4 5#define rep(i,n) for(int (i) = 0; (i) < (n); ++(i)) 6 7template<class Abel> struct D_Graph { 8 int V,E; 9 bool **exist; 10 vector<vector<pair<int,Abel>>> adj; 11 vector<vector<pair<int,Abel>>> adj_inv; 12 13 D_Graph(int V_size = 0) : V(V_size) 14 { 15 init(V); 16 } 17 18 void init(int V) { 19 exist = (bool**)malloc(sizeof(bool*) * (V + 1)); 20 for(int i = 0; i <= V; ++i){ 21 exist[i] = (bool*)malloc(sizeof(bool) * (V + 1)); 22 fill(exist[i],exist[i] + V + 1,0); 23 } 24 adj.clear(); 25 adj_inv.clear(); 26 adj.resize(V + 1); 27 adj_inv.resize(V + 1); 28 for(int i = 1; i <= V; ++i){ 29 adj[0].push_back({i,0}); 30 exist[0][i] = 1; 31 } 32 E = 0; 33 } 34 35 int deg_out(int v) { return adj[v].size(); } 36 37 int deg_in(int v) { return adj_inv[v].size(); } 38 39 bool is_leaf(int v) { return deg_out(v) == 0; } 40 41 bool is_root(int v) { return deg_in(v) == 0; } 42 43 void add_edge(int from, int to, Abel cost = 1) { 44 adj[from].push_back({to,cost}); 45 adj_inv[to].push_back({from,cost}); 46 exist[from][to] = 1; 47 ++E; 48 } 49 50 bool tsort(vector<int> &seq, bool idx_ordered = 0) { 51 seq.reserve(V); 52 vector<int> in(V + 1); 53 stack<int> rt; 54 for(int i = 1; i <= V; ++i){ 55 in[i] = deg_in(i); 56 if(!in[i]){ 57 rt.push(i); 58 seq.push_back(i); 59 } 60 } 61 while(!rt.empty()){ 62 int r = rt.top(); 63 rt.pop(); 64 for(auto e : adj[r]){ 65 int v = e.first; 66 --in[v]; 67 if(!in[v]){ 68 rt.push(v); 69 if(idx_ordered){ 70 int pos = 0; 71 for(int i = 0; i < seq.size(); ++i) if(seq[i] < v || exist[seq[i]][v]) pos = i + 1; 72 seq.insert(begin(seq) + pos,v); 73 }else{ 74 seq.push_back(v); 75 } 76 } 77 } 78 } 79 if(seq.size() == V) return 1; 80 return 0; 81 } 82}; 83 84int main(){ 85 86 D_Graph<int> G(26); 87 int N; cin>>N; 88 string a,b; 89 rep(j,N){ 90 cin>>a>>b; 91 rep(i,min(a.size(),b.size())){ 92 if(a[i] != b[i]){ 93 G.add_edge(a[i] - 'a' + 1,b[i] - 'a' + 1); 94 break; 95 } 96 if(i + 1 == b.size()){ cout<<-1<<endl; return 0; } 97 } 98 } 99 vector<int> seq; 100 bool j = G.tsort(seq,1); 101 if(j){ 102 for(int c : seq) cout<<(char)(c - 1 + 'a'); 103 }else{ 104 cout<<-1; 105 } 106 cout<<endl; 107 108 return 0; 109} 110 111 112 113

補足

D_Graph構造体のメンバ関数tsortが重要な部分になっています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

自己解決しました(下のコードで通すことができました)。
入次数0の頂点を互いを結ぶ辺がないようにまとめて優先度付き降順キューで持ち、
取り出しながらそこまでのソート列にその時点で辞書順を最小化できるように挿入していくことで実現できました。
予め色々なケース(特に自分のコードが対処を困難とするもの)を想定できるようになることも大切ですね。まだまだ精進が必要だと実感しました。

https://beta.atcoder.jp/contests/tenka1-2016-quala/submissions/2858520

投稿2018/07/17 04:52

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問