白準系譜復元家胡石(21276)
23186 ワード
系譜復元家胡石
昇順で出力するので、与えられた人の名前を並べ替えてみましょう.次に、(番号、、、名前)として保存します.Mapを処理(名前、、、番号)として宣言すると便利です.
1.ヒント
住民たちはすべての祖先をよく覚えている。したがって、指定した情報を使用して作成できるツリーは1つだけです。
2)X→YXto YX→Yを逆に考え、YYからXXXまでの幹線と考える。これで、各レベルが000の頂点になると、各家族の始祖がわかるようになります。
3)位相整列を使用して高さ000の頂点を更新し、グラフィックを構成する場合は、ツリーのルートディレクトリから情報を下に表示できます。
2.近接
1) Map
昇順で出力するので、与えられた人の名前を並べ替えてみましょう.次に、(番号、、、名前)として保存します.Mapを処理(名前、、、番号)として宣言すると便利です.
3.実施
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder bw = new StringBuilder();
int N = Integer.parseInt(br.readLine());
String[] S = new String[N];
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
for (int i = 0; i < N; i++) S[i] = st.nextToken();
Arrays.sort(S);
// 이름이 주어지면 사전순으로 정렬했을 때 몇 번째인지 반환하는 map
Map<String, Integer> m = new HashMap<>();
for (int i = 0; i < N; i++) m.put(S[i], i);
// 위상정렬을 위해 어떤 정점에 들어오는 간선의 개수 저장
// X -> Y : X의 조상 중 Y가 있다
// 가장 위에 있는 조상부터 고를 수 있도록 간선의 방향은 Y -> X가 됨
int[] indegree = new int[N];
boolean[][] adj = new boolean[N][N];
int M = Integer.parseInt(br.readLine());
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine(), " ");
int u = m.get(st.nextToken());
int v = m.get(st.nextToken());
adj[v][u] = true;
indegree[u]++;
}
// 들어오는 간선이 없는 정점은 시조
int cnt = 0;
for (int i = 0; i < N; i++)
if (indegree[i] == 0) cnt++;
bw.append(cnt).append("\n");
Queue<Integer> q = new LinkedList<>();
// 사전순으로 출력해야하므로 정렬된 배열 S의 순서에 맞게 큐에 삽입
for (int i = 0; i < N; i++) if (indegree[i] == 0) {
bw.append(S[i]).append(" ");
q.offer(i);
}
bw.append("\n");
// i번째 정점의 자식들을 사전순으로 정렬하기 위해서 우선순위 큐 사용
ArrayList<PriorityQueue<Integer>> T = new ArrayList<>(N);
for (int i = 0; i <= N; i++) T.add(new PriorityQueue<>());
for (int i = 0; i < N; i++) {
// indegree가 0인 가장 조상인 정점을 뽑는다
int here = q.poll();
for (int there = 0; there < N; there++) if (adj[here][there]) {
indegree[there]--;
// 새롭게 indgree가 0인 정점이 있으면 큐에 삽입
// 마찬가지로 S는 정렬되어 있으므로 큐에는 오름차순으로 들어감
if (indegree[there] == 0) {
q.offer(there);
T.get(here).offer(there);
}
}
}
for (int i = 0; i < N; i++) {
bw.append(S[i]).append(" ");
bw.append(T.get(i).size()).append(" ");
PriorityQueue<Integer> pq = T.get(i);
while (!pq.isEmpty()) bw.append(S[pq.poll()]).append(" ");
bw.append("\n");
}
System.out.print(bw);
}
}
Reference
この問題について(白準系譜復元家胡石(21276)), 我々は、より多くの情報をここで見つけました https://velog.io/@axiom0510/b21276テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol