static void Main() { Console.SetOut(new System.IO.StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false }); var h = Read(); int n = h[0], qc = h[1]; var qs = Array.ConvertAll(new bool[qc], _ => Read()); var uf = new UF(n); foreach (var q in qs) { if (q[0] == 0) { uf.Unite(q[1], q[2]); } else { Console.WriteLine(uf.AreUnited(q[1], q[2]) ? 1 : 0); } } Console.Out.Flush(); }
static void Main() { var h = Read(); var n = h[0]; var ab = new int[h[1]].Select(_ => Read()).ToArray(); var cd = new int[h[2]].Select(_ => Read()).ToArray(); var uf = new UF(n + 1); foreach (var x in ab) { uf.Unite(x[0], x[1]); } var roots = Enumerable.Range(0, n + 1).GroupBy(uf.GetRoot).ToDictionary(g => g.Key, g => g.Count()); var c = Enumerable.Range(0, n + 1).Select(uf.GetRoot).Select(x => roots[x] - 1).ToArray(); foreach (var x in ab) { c[x[0]]--; c[x[1]]--; } foreach (var x in cd) { if (!uf.AreUnited(x[0], x[1])) { continue; } c[x[0]]--; c[x[1]]--; } Console.WriteLine(string.Join(" ", c.Skip(1))); }
static object Solve() { var(n, m) = Read2(); var es = Array.ConvertAll(new bool[m], _ => Read2()); var uf = new UF(n + 1); var vs = new List <int>(); foreach (var e in es) { if (uf.AreUnited(e.u, e.v)) { vs.Add(e.u); } else { uf.Unite(e.u, e.v); } } if (vs.Select(uf.GetRoot).Distinct().Count() != vs.Count) { return(0); } if (uf.GroupsCount - 1 != vs.Count) { return(0); } return(MPow(2, vs.Count)); }
static void Main() { var n = int.Parse(Console.ReadLine()); var qc = int.Parse(Console.ReadLine()); var qs = Array.ConvertAll(new bool[qc], _ => Read4()); var roots = new int[n + 1]; var d = new long[n + 1]; foreach (var(_, x, y, v) in qs.Where(q => q.t == 0).OrderBy(q => q.x)) { if (roots[x] == -1) { roots[x] = x; } roots[y] = roots[x]; d[y] = v - d[x]; } var uf = new UF(n + 1); Console.SetOut(new System.IO.StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false }); foreach (var(t, x, y, v) in qs) { if (t == 0) { uf.Unite(x, y); } else { if (uf.AreUnited(x, y)) { var v0 = (x - roots[x]) % 2 == 0 ? v - d[x] : d[x] - v; var vy = (y - roots[y]) % 2 == 0 ? d[y] + v0 : d[y] - v0; Console.WriteLine(vy); } else { Console.WriteLine("Ambiguous"); } } } Console.Out.Flush(); }
// 連結な無向グラフから無向木を取り出します。 static int[][] GetUndirectedTree(int n, int[][] ues) { var uf = new UF(n); var res = new List <int[]>(); foreach (var e in ues) { if (uf.AreUnited(e[0], e[1])) { continue; } uf.Unite(e[0], e[1]); res.Add(e); } return(res.ToArray()); }
static Edge[] Kruskal(int n, Edge[] ues) { var uf = new UF(n); var mes = new List <Edge>(); foreach (var e in ues.OrderBy(e => e.cost)) { if (uf.AreUnited(e.i, e.j)) { continue; } uf.Unite(e.i, e.j); mes.Add(e); } return(mes.ToArray()); }
static int[][] Kruskal(int n, int[][] ues) { var uf = new UF(n); var mes = new List <int[]>(); foreach (var e in ues.OrderBy(e => e[2])) { if (uf.AreUnited(e[0], e[1])) { continue; } uf.Unite(e[0], e[1]); mes.Add(e); } return(mes.ToArray()); }
static void Main() { var(h, w) = Read2(); var qc = int.Parse(Console.ReadLine()); h += 2; w += 2; int ToId(int i, int j) => i * w + j; int[] Nexts(int id) => new[] { id + 1, id - 1, id + w, id - w }; var u = new bool[h * w]; var uf = new UF(h * w); Console.SetOut(new System.IO.StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false }); for (int k = 0; k < qc; k++) { var q = Read(); if (q[0] == 1) { var(i, j) = (q[1], q[2]); var p = ToId(i, j); u[p] = true; foreach (var np in Nexts(p)) { if (u[np]) { uf.Unite(p, np); } } } else { var(ai, aj, bi, bj) = (q[1], q[2], q[3], q[4]); var a = ToId(ai, aj); var b = ToId(bi, bj); Console.WriteLine(u[a] && u[b] && uf.AreUnited(a, b) ? "Yes" : "No"); } } Console.Out.Flush(); }
public static int[][] Kruskal(int n, int[][] ues) { var uf = new UF(n); var mes = new List <int[]>(); foreach (var e in ues.OrderBy(e => e[2])) { if (uf.AreUnited(e[0], e[1])) { continue; } uf.Unite(e[0], e[1]); mes.Add(e); // 実際の頂点数に注意。 // あまり実行速度に影響しないようです。 //if (mes.Count == n - 1) break; } return(mes.ToArray()); }
// Partitioning static (int[][], int[][]) GetUndirectedTree(int n, int[][] ues) { var uf = new UF(n); var res = new List <int[]>(); var res2 = new List <int[]>(); foreach (var e in ues) { if (uf.AreUnited(e[0], e[1])) { res2.Add(e); } else { uf.Unite(e[0], e[1]); res.Add(e); } } return(res.ToArray(), res2.ToArray()); }
static void Main() { Func <int[]> read = () => Console.ReadLine().Split().Select(int.Parse).ToArray(); var h = read(); var uf = new UF(h[0]); var l = new List <string>(); foreach (var q in new int[h[1]].Select(_ => read())) { if (q[0] == 0) { uf.Unite(q[1], q[2]); } else { l.Add(uf.AreUnited(q[1], q[2]) ? "Yes" : "No"); } } Console.WriteLine(string.Join("\n", l)); }
static void Main() { var r = new List <int>(); var h = Read(); var n = h[0]; var uf = new UF(n); for (int i = 0; i < h[1]; i++) { var q = Read(); if (q[0] == 0) { uf.Unite(q[1], q[2]); } else { r.Add(uf.AreUnited(q[1], q[2]) ? 1 : 0); } } Console.WriteLine(string.Join("\n", r)); }
static void Main() { var(n, m) = Read2(); var uf = new UF(n); foreach (var r in new int[m].Select(_ => Read())) { uf.Unite(r[0], r[1]); } var q = int.Parse(Console.ReadLine()); Console.WriteLine(string.Join("\n", new int[q].Select(_ => Read()).Select(r => uf.AreUnited(r[0], r[1]) ? "yes" : "no"))); }
static void Main() { var h = Read(); var n = h[0]; var es = new int[h[1]].Select(_ => Read()).ToArray(); var qs = new int[int.Parse(Console.ReadLine())].Select(_ => Read()).ToArray(); var map = Array.ConvertAll(new int[n], _ => new List <int>()); var map_r = Array.ConvertAll(new int[n], _ => new List <int>()); foreach (var e in es) { map[e[0]].Add(e[1]); map_r[e[1]].Add(e[0]); } var uf = new UF(n); var u = new bool[n]; var order = new List <int>(); Action <int> Dfs = null; Dfs = v => { u[v] = true; foreach (var nv in map[v]) { if (u[nv]) { continue; } Dfs(nv); } order.Add(v); }; for (int v = 0; v < n; v++) { if (!u[v]) { Dfs(v); } } Action <int> Dfs_r = null; Dfs_r = v => { u[v] = true; foreach (var nv in map_r[v]) { if (u[nv]) { continue; } uf.Unite(v, nv); Dfs_r(nv); } }; Array.Clear(u, 0, n); order.Reverse(); foreach (var v in order) { if (!u[v]) { Dfs_r(v); } } Console.WriteLine(string.Join("\n", qs.Select(v => uf.AreUnited(v[0], v[1]) ? 1 : 0))); }
static void Main() { var(h, w) = Read2(); // 1-indexed に注意 var sv = Read2(); var ev = Read2(); var s = GridHelper.ReadEnclosedGrid(ref h, ref w); sv = (sv.i + 1, sv.j + 1); ev = (ev.i + 1, ev.j + 1); GridHelper.EncloseGrid(ref h, ref w, ref s); const char Wall = '#'; var idMap = new int[h, w]; for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { idMap[i, j] = i * w + j; } } var uf = new UF(h * w); for (int i = 2; i < h - 2; i++) { for (int j = 2; j < w - 2; j++) { if (s[i][j] == Wall) { continue; } if (s[i - 1][j] != Wall) { uf.Unite(idMap[i, j], idMap[i - 1, j]); } if (s[i][j - 1] != Wall) { uf.Unite(idMap[i, j], idMap[i, j - 1]); } } } var es = new List <(int v1, int v2)>(); var sv2 = uf.GetRoot(idMap[sv.i, sv.j]); var ev2 = uf.GetRoot(idMap[ev.i, ev.j]); for (int i = 2; i < h - 2; i++) { for (int j = 2; j < w - 2; j++) { if (s[i][j] == Wall) { continue; } var id = idMap[i, j]; for (int di = -2; di <= 0; di++) { for (int dj = -2; dj <= 2; dj++) { if (s[i + di][j + dj] == Wall) { continue; } var did = idMap[i + di, j + dj]; if (uf.AreUnited(id, did)) { continue; } var(v1, v2) = (uf.GetRoot(id), uf.GetRoot(did)); if (v1 > v2) { (v1, v2) = (v2, v1); } es.Add((v1, v2)); } } } } var r = ShortestPath.Bfs(h * w, es.Distinct().Select(e => new[] { e.v1, e.v2 }).ToArray(), false, sv2, ev2); Console.WriteLine(r.IsConnected(ev2) ? r[ev2] : -1); }
static void Main() { var h = Read(); int n = h[0], m = h[1]; var rs = new int[m].Select(_ => Read()).Select((x, id) => (id, a: x[0], b: x[1], c: (long)x[2])).ToArray(); var n2 = Enumerable.Range(0, 20).Select(i => 1 << i).First(x => x >= n - 1); var uf = new UF(n + 1); var minEdges = new List <int>(); var extraEdges = new int[n2].Select(_ => new List <int>()).ToArray(); var maxCost = new long[m]; foreach (var r in rs.OrderBy(r => r.c)) { if (!uf.AreUnited(r.a, r.b)) { uf.Unite(r.a, r.b); minEdges.Add(r.id); } else { extraEdges[n2 >> 1].Add(r.id); } } var minCost = minEdges.Sum(id => rs[id].c); // 並列二分探索。 for (int f = n2 >> 1; f > 0; f >>= 1) { var uf2 = new UF(n + 1); for (int i = 0; i < n2; i++) { // unite する前に判定します。 if (i % f == 0 && i / f % 2 == 1) { foreach (var id in extraEdges[i]) { var(_, a, b, _) = rs[id]; if (f > 1) { if (uf2.AreUnited(a, b)) { extraEdges[i - (f >> 1)].Add(id); } else { extraEdges[i + (f >> 1)].Add(id); } } else { var maxIndex = uf2.AreUnited(a, b) ? i - 1 : i; maxCost[id] = rs[minEdges[maxIndex]].c; } } extraEdges[i].Clear(); } if (i < n - 1) { var r = rs[minEdges[i]]; uf2.Unite(r.a, r.b); } } } Console.WriteLine(string.Join("\n", maxCost.Select((x, id) => x == 0 ? minCost : minCost + rs[id].c - x))); }
static int MinCostArborescence(int n, int sv, List <int[]>[] map, UF uf) { // 入る辺のうち最小のもの。 var minEdges = new int[n][]; for (int v = 0; v < n; v++) { if (v == sv || map[v]?.Any() != true) { continue; } var min = map[v].Min(e => e[2]); minEdges[v] = map[v].First(e => e[2] == min); uf.Unite(v, minEdges[v][0]); } var rn = Enumerable.Range(0, n).ToArray(); if (rn.All(v => uf.AreUnited(v, sv))) { return(minEdges.Sum(e => e?[2] ?? 0)); } // 根と非連結になっているパスのうち、サイクルとなっている部分を縮約します。 // 0 型と 6 型のいずれか。 var sum = 0; var u = new bool[n]; var reductMap = new int[n]; for (int v = 0; v < n; v++) { if (uf.AreUnited(v, sv)) { map[v].Clear(); sum += minEdges[v]?[2] ?? 0; reductMap[v] = sv; continue; } if (u[v]) { continue; } var cycle = Array.FindAll(rn, i => uf.AreUnited(v, i)); foreach (var i in cycle) { u[i] = true; } // vc0 に縮約します。 var vc0 = cycle[0]; var gs2 = cycle.Where(i => minEdges[i] != null).Select(i => minEdges[i][0]).GroupBy(i => i).Where(g => g.Count() == 2).ToArray(); if (gs2.Any()) { // 6 型の場合。 vc0 = gs2[0].Key; var path = new List <int> { vc0 }; for (var t = vc0; (t = minEdges[t][0]) != vc0;) { path.Add(t); } cycle = path.ToArray(); } var cycleSum = cycle.Sum(i => minEdges[i]?[2] ?? 0); foreach (var i in cycle) { reductMap[i] = vc0; map[i].RemoveAll(e => uf.AreUnited(e[0], e[1])); if (i == vc0) { foreach (var e in map[i]) { e[2] += cycleSum - minEdges[i][2]; } } else { foreach (var e in map[i]) { e[2] += cycleSum - minEdges[i][2]; map[vc0].Add(e); } map[i].Clear(); } } } foreach (var es in map) { foreach (var e in es) { e[0] = reductMap[e[0]]; e[1] = reductMap[e[1]]; } } return(MinCostArborescence(n, sv, map, uf) + sum); }