AOJ Network Mess
問題
無向木であらわされる、コンピュータとスイッチのネットワークがある。
スイッチは全て木の内点であり、コンピュータは木の葉である。
全てのコンピュータは、それぞれただ一つのスイッチとつながっていて、
全てのスイッチには少なくとも一つのコンピュータがつながっている。
今、コンピュータ同士のネットワーク上の距離行列が与えられる。
元のネットワークでのスイッチに相当する頂点を、次数の小さい順に並べて出力せよ。
制約条件
コンピュータの数≦50
コンピュータ同士の距離は30以下
方針
0〜i番目のコンピュータまでを使ったネットワークがわかっているとき、
i+1番目のコンピュータがどこに入るかは、距離行列から一意に定まる。
n≦50と小さいので、全通り試しても余裕で間に合う。
なので全通り試す。
これをi = 0からはじめてn-1まで順に繰り返せばいい。
ソースコード
int n, m, d[1000][1000]; vi e[1000]; map<int, int> to; int dist[1000], num[1000]; int main() { while(cin >> n, n){ m = 0; to.clear(); rep(i, 1000) e[i].clear(); rep(i, 1000) num[i] = -1; rep(i, n) rep(j, n) cin >> d[i][j]; to[0] = m++; num[0] = 0; for(int i = 1; i < n; i++){ rep(j, m){ rep(k, m) dist[k] = -1; dist[j] = 0; int len = -1; queue<int> q; q.push(j); while(!q.empty()){ int c = q.front(); q.pop(); if(num[c] >= 0){ if(len < 0){ len = d[i][num[c]] - dist[c] - 2; if(len < 0) goto FAIL; } else if(len != d[i][num[c]] - dist[c] - 2) goto FAIL; } rep(k, e[c].size()) if(dist[e[c][k]] < 0){ dist[e[c][k]] = dist[c] + 1; q.push(e[c][k]); } } rep(k, len){ e[j].pb(m); e[m].pb(j); j = m++; } to[i] = j; num[j] = i; break; FAIL:; } } int deg[1000] = {}; rep(i, m) deg[i] = e[i].size(); fr(i, to) deg[i->second]++; vi ans; rep(i, 1000) if(deg[i]) ans.pb(deg[i]); sort(all(ans)); rep(i, ans.size()) cout << ans[i] << (i == (int)ans.size() - 1 ? "\n" : " "); } return 0; }