グラフ構造の入力メニュー【頂点の出現回数・オイラーグラフ・準オイラーグラフ・(入出)次数・しりとり】
【STEP: 1】コード 1 ( 隣接行列 )
reader.on('close', () => {
function adjacency_Matrix(a, b) { // 隣接行列の値を更新
Matrix[a][b]++;
Matrix[b][a]++;
}
const Matrix = []; // 隣接行列
const [N, M, V] = lines[0].split(' ').map(Number);
for (let i = 0; i < N; i++) {
Matrix[i] = new Array(N).fill(0);
}
for (let i = 1; i <= M; i++) {
const [A, B] = lines[i].split(' ').map(e => e - 1);
adjacency_Matrix(A, B);
}
// console.log(Matrix); // [ [ 0, 1, 0 ], [ 1, 0, 1 ], [ 0, 1, 0 ] ]
const num_of_Apex = Matrix[V -1].reduce((acc, cur) => acc + cur);
console.log(num_of_Apex);
});
配列 Matrix (N ✕ N の 2次元配列) は 無向グラフの隣接行列です。
Matrix[V -1]
の値を足し算すれば 頂点の出現回数 と一致しました。
【STEP: 1】コード 2 ( 隣接リスト )
reader.on('close', () => {
function adjacency_List(a, b) {
List[a].push(b);
List[b].push(a);
}
const List = []; // 隣接リスト
const [N, M, V] = lines[0].split(' ').map(Number);
for (let i = 0; i < N; i++) {
List.push([]);
}
for (let i = 1; i <= M; i++) {
const [A, B] = lines[i].split(' ').map(e => e - 1);
adjacency_List(A, B);
}
console.log(List[V - 1].length);
});
配列 List (N 行 の 2次元配列) は 無向グラフの隣接リストです。
頂点の出現回数は各行の要素数と一致しました。
【STEP: 2】コード 1 ( 隣接行列 )
reader.on('close', () => {
function adjacency_Matrix(a, b) { // 隣接行列の値を更新
Matrix[a][b]++;
Matrix[b][a]++;
}
const Matrix = []; // 隣接行列
const [N, M] = lines[0].split(' ').map(Number);
for (let i = 0; i < N; i++) {
Matrix[i] = new Array(N).fill(0);
}
for (let i = 1; i <= M; i++) {
const [A, B] = lines[i].split(' ').map(e => e - 1);
adjacency_Matrix(A, B);
}
// console.table(Matrix);
const degree = new Array(N); // 各頂点の次数
for (let i = 0; i < N; i++) {
degree[i] = Matrix[i].reduce((acc, cur) => acc + cur);
}
console.log(...degree);
});
次数…各頂点を接続している辺の数。
隣接行列の行の値を足し合わせて次数を求めています。
【STEP: 2】コード 2 ( 隣接リスト )
reader.on('close', () => {
function adjacency_List(a, b) {
List[a].push(b);
List[b].push(a);
}
const List = []; // 隣接リスト
const [N, M] = lines[0].split(' ').map(Number);
for (let i = 0; i < N; i++) {
List.push([]);
}
for (let i = 1; i <= M; i++) {
const [A, B] = lines[i].split(' ').map(e => e - 1);
adjacency_List(A, B);
}
const degree = new Array(N); // 各頂点の次数
for (let i = 0; i < N; i++) {
degree[i] = List[i].length;
}
console.log(...degree);
});
List[i].length
で 次数 を 求めることができました。
【STEP: 3】コード 1
reader.on('close', () => {
function adjacency_Matrix(a, b) { // 隣接行列の値を更新
Matrix[a][b]++;
Matrix[b][a]++;
}
const Matrix = []; // 隣接行列
const [N, M] = lines[0].split(' ').map(Number);
for (let i = 0; i < N; i++) {
Matrix[i] = new Array(N).fill(0);
}
for (let i = 1; i <= M; i++) {
const [A, B] = lines[i].split(' ').map(e => e - 1);
adjacency_Matrix(A, B);
}
// console.table(Matrix);
let Eulerian_graph = true;
for (let i = 0; i < N; i++) {
const edges = Matrix[i].reduce((acc, cur) => acc + cur);
if (edges % 2) {
Eulerian_graph = false;
}
}
console.log(Number(Eulerian_graph));
});
連結なグラフ…どの 2 つの頂点間も辺をたどって行き来ができるグラフ。
一筆書き(閉じた線)できる…すべての頂点の次数が偶数。
【STEP: 3】コード 2 ( 隣接リスト )
reader.on('close', () => {
function adjacency_List(a, b) {
List[a].push(b);
List[b].push(a);
}
const List = []; // 隣接リスト
const [N, M] = lines[0].split(' ').map(Number);
for (let i = 0; i < N; i++) {
List.push([]);
}
for (let i = 1; i <= M; i++) {
const [A, B] = lines[i].split(' ').map(e => e - 1);
adjacency_List(A, B);
}
let Eulerian_graph = true;
for (let i = 0; i < N; i++) {
const edges = List[i].length;
if (edges % 2) {
Eulerian_graph = false;
}
}
console.log(Number(Eulerian_graph));
});
頂点 I の次数は List[i].length
。
【STEP: 4】コード
reader.on('close', () => {
function adjacency_Matrix(a, b) { // 隣接行列の値を更新
Matrix[a][b]++;
Matrix[b][a]++;
}
const Matrix = []; // 隣接行列
const [N, M] = lines[0].split(' ').map(Number);
for (let i = 0; i < N; i++) {
Matrix[i] = new Array(N).fill(0);
}
for (let i = 1; i <= M; i++) {
const [A, B] = lines[i].split(' ').map(e => e - 1);
adjacency_Matrix(A, B);
}
// console.table(Matrix);
let degree = 0;
for (let i = 0; i < N; i++) {
edges = Matrix[i].reduce((acc, cur) => acc + cur);
if (edges % 2) {
degree++;
}
}
console.log(degree === 2 || degree === 0 ? 1 : 0);
});
一筆書きできる…次数が奇数である頂点数が 0 または 2 。
【STEP: 5】コード
reader.on('close', () => {
function adjacency_List(a, b) {
List[a].push(b + 1);
}
const List = []; // 隣接リスト
const [N, M, V] = lines[0].split(' ').map(Number);
for (let i = 0; i < N; i++) {
List.push([]);
}
for (let i = 1; i <= M; i++) {
const [A, B] = lines[i].split(' ').map(e => e - 1);
adjacency_List(A, B);
}
// console.table(List);
const outdegree = List[V - 1].length;
let indegree = 0;
for (let i = 0; i < N; i++) {
for (let j = 0; j < N; j++) {
if (List[i][j] === V) {
indegree++;
}
}
}
console.log(outdegree, indegree);
});
有向グラフ…辺に向きがつけられているグラフ。
【STEP: 6】コード
reader.on('close', () => {
function adjacency_List(a, b) {
List[a].push(b + 1);
}
const List = []; // 隣接リスト
const [N, M] = lines[0].split(' ').map(Number);
for (let i = 0; i < N; i++) {
List.push([]);
}
for (let i = 1; i <= M; i++) {
const [A, B] = lines[i].split(' ').map(e => e - 1);
adjacency_List(A, B);
}
// console.table(List);
const outdegree = new Array(N);
const indegree = new Array(N).fill(0);
for (let i = 0; i < N; i++) {
outdegree[i] = List[i].length;
for (let j = 0; j < List[i].length; j++) {
for (let k = 1; k <= N; k++) {
if (List[i][j] === k) {
indegree[k - 1]++;
}
}
}
}
console.log(...indegree);
console.log(...outdegree);
});
入次数…頂点 i に向かっている辺の個数。
出次数…頂点 i から出ている辺の個数。
【STEP: 7】コード
reader.on('close', () => {
function adjacency_List(a, b) {
List[a].push(b + 1);
}
const List = []; // 隣接リスト
const [N, M] = lines[0].split(' ').map(Number);
for (let i = 0; i < N; i++) {
List.push([]);
}
for (let i = 1; i <= M; i++) {
const [A, B] = lines[i].split(' ').map(e => e - 1);
adjacency_List(A, B);
}
// console.table(List);
const outdegree = new Array(N);
const indegree = new Array(N).fill(0);
let weakly_connected = true;
for (let i = 0; i < N; i++) {
outdegree[i] = List[i].length;
for (let j = 0; j < List[i].length; j++) {
for (let k = 1; k <= N; k++) {
if (List[i][j] === k) {
indegree[k - 1]++;
}
}
}
}
for (let i = 0; i < N; i++) {
if (outdegree[i] !== indegree[i]) {
weakly_connected = false;
}
}
console.log(Number(weakly_connected));
});
一筆書き(条件)…全ての頂点の入次数と出次数が一致する。
【STEP: 8】コード
reader.on('close', () => {
function adjacency_List(a, b) {
List[a].push(b + 1);
}
const List = []; // 隣接リスト
const [N, M] = lines[0].split(' ').map(Number);
for (let i = 0; i < N; i++) {
List.push([]);
}
for (let i = 1; i <= M; i++) {
const [A, B] = lines[i].split(' ').map(e => e - 1);
adjacency_List(A, B);
}
// console.table(List);
const outdegree = new Array(N);
const indegree = new Array(N).fill(0);
let one_stroke = true;
for (let i = 0; i < N; i++) {
outdegree[i] = List[i].length;
for (let j = 0; j < List[i].length; j++) {
for (let k = 1; k <= N; k++) {
if (List[i][j] === k) {
indegree[k - 1]++;
}
}
}
}
const obs_1 = [0, 0];
for (let i = 0; i < N; i++) {
if (outdegree[i] !== indegree[i]) {
one_stroke = false;
}
if (outdegree[i] - indegree[i] === 1) {
obs_1[0]++;
}
if (indegree[i] - outdegree[i] === 1) {
obs_1[1]++;
}
}
if (obs_1[1] === 1 && obs_1[1] === 1) {
one_stroke = true;
}
console.log(Number(one_stroke));
});
弱連結…無向グラフとしてみた場合どの頂点間も辺をたどって行き来できる。
【FINAL】コード
reader.on('close', () => {
function Word_Chain(a, b) {
alphabet[a].push(b);
}
const alphabet = []; // 隣接リスト
for (let i = 0; i < 26; i++) {
alphabet.push([]);
}
const a = 'a'.codePointAt();
const N = Number(lines[0]);
for (let i = 1; i <= N; i++) {
const S = lines[i];
const L = S.length - 1;
const s_f = S[0].codePointAt() - a;
const s_l = S[L].codePointAt() - a;
Word_Chain(s_f, s_l);
}
const outdegree = new Array(26);
const indegree = new Array(26).fill(0);
let chain = true;
for (let i = 0; i < 26; i++) {
outdegree[i] = alphabet[i].length;
for (let j = 0; j < alphabet[i].length; j++) {
for (let k = 0; k < 26; k++) {
if (alphabet[i][j] === k) {
indegree[k]++;
}
}
}
}
const obs_1 = [0, 0];
for (let i = 0; i < 26; i++) {
if (outdegree[i] !== indegree[i]) {
chain = false;
}
if (outdegree[i] - indegree[i] === 1) {
obs_1[0]++;
}
if (indegree[i] - outdegree[i] === 1) {
obs_1[1]++;
}
}
if (obs_1[1] === 1 && obs_1[1] === 1) {
chain = true;
}
console.log(Number(chain));
// console.log(indegree);
// console.log(outdegree);
});
アルファベットの文字コードナンバーを取得して 有向グラフ化しています。
コメント