export interface GraphNode {
id: string;
width?: number;
height?: number;
selected?: boolean;
logLevel?: number;
}
export interface GraphEdge {
source: string;
target: string;
}
class UnionFind {
private parent: { [key: string]: string };
private rank: { [key: string]: number };
constructor() {
this.parent = {};
this.rank = {};
}
find(node: string): string {
if (!(node in this.parent)) {
this.parent[node] = node;
this.rank[node] = 0;
}
if (this.parent[node] !== node) {
this.parent[node] = this.find(this.parent[node]);
}
return this.parent[node];
}
union(node1: string, node2: string): void {
const root1 = this.find(node1);
const root2 = this.find(node2);
if (root1 !== root2) {
if (this.rank[root1] > this.rank[root2]) {
this.parent[root2] = root1;
} else if (this.rank[root1] < this.rank[root2]) {
this.parent[root1] = root2;
} else {
this.parent[root2] = root1;
this.rank[root1]++;
}
}
}
}
function canAddEdge(edges: GraphEdge[], newEdge: GraphEdge): boolean {
const unionFind = new UnionFind();
for (const edge of edges) {
const { source, target } = edge;
if (unionFind.find(source) === unionFind.find(target)) {
continue;
}
unionFind.union(source, target);
}
const { source, target } = newEdge;
if (unionFind.find(source) === unionFind.find(target)) {
return false;
}
return true;
}
const nodes: GraphNode[] = [
{ id: 'A' },
{ id: 'B' },
{ id: 'C' },
{ id: 'D' },
];
const edges: GraphEdge[] = [
{ source: 'A', target: 'B' },
{ source: 'B', target: 'C' },
];
const newEdge: GraphEdge = { source: 'A', target: 'C' };
console.log(canAddEdge(edges, newEdge));
const anotherNewEdge: GraphEdge = { source: 'C', target: 'D' };
console.log(canAddEdge(edges, anotherNewEdge));