Skip to content

Instantly share code, notes, and snippets.

@jianminchen
Created July 21, 2016 05:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jianminchen/7a21dfe2a62f1bcf4bc305480ef2f51e to your computer and use it in GitHub Desktop.
Save jianminchen/7a21dfe2a62f1bcf4bc305480ef2f51e to your computer and use it in GitHub Desktop.
HackerRank: World codesprint #4 - Roads in HackerLand - study C# code
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
public class Solver
{
class Dsu
{
private readonly int[] parent;
public Dsu(int n)
{
parent = Enumerable.Range(0, n).ToArray();
}
public int FindSet(int v)
{
if (v == parent[v])
return v;
return parent[v] = FindSet(parent[v]);
}
public void UnionSets(int a, int b)
{
a = FindSet(a);
b = FindSet(b);
if (a != b)
parent[b] = a;
}
}
public void Solve()
{
int n = ReadInt();
int m = ReadInt();
var ed = ReadIntMatrix(m);
Array.Sort(ed, (e1, e2) => e1[2].CompareTo(e2[2]));
var dsu = new Dsu(n);
var g = Init<List<Tuple<int, int>>>(n);
for (int i = 0; i < m; i++)
{
ed[i][0]--;
ed[i][1]--;
if (dsu.FindSet(ed[i][0]) != dsu.FindSet(ed[i][1]))
{
g[ed[i][0]].Add(Tuple.Create(ed[i][1], ed[i][2]));
g[ed[i][1]].Add(Tuple.Create(ed[i][0], ed[i][2]));
dsu.UnionSets(ed[i][0], ed[i][1]);
}
}
var stack = new Stack<Tuple<int, int>>();
var stack2 = new Stack<Tuple<int, int>>();
stack.Push(Tuple.Create(0, -1));
while (stack.Count > 0)
{
var t = stack.Pop();
foreach (var e in g[t.Item1])
if (e.Item1 != t.Item2)
stack.Push(Tuple.Create(e.Item1, t.Item1));
stack2.Push(t);
}
var cnt = new int[n];
while (stack2.Count > 0)
{
var t = stack2.Pop();
cnt[t.Item1] = 1;
foreach (var e in g[t.Item1])
if (e.Item1 != t.Item2)
cnt[t.Item1] += cnt[e.Item1];
}
var stack3 = new Stack<Tuple<int, int, int>>();
var ans = Enumerable.Repeat(0L, m).ToList();
stack3.Push(Tuple.Create(0, -1, 0));
while (stack3.Count > 0)
{
var t = stack3.Pop();
foreach (var e in g[t.Item1])
if (e.Item1 != t.Item2)
{
ans[e.Item2] = 1L * cnt[e.Item1] * (cnt[t.Item1] - cnt[e.Item1] + t.Item3);
stack3.Push(Tuple.Create(e.Item1, t.Item1, t.Item3 + cnt[t.Item1] - cnt[e.Item1]));
}
}
for (int i = 0; i < ans.Count; i++)
{
long ex = ans[i] / 2;
ans[i] %= 2;
if (ex > 0)
{
if (i == ans.Count - 1)
ans.Add(0);
ans[i + 1] += ex;
}
}
while (ans[ans.Count - 1] == 0)
ans.RemoveAt(ans.Count - 1);
ans.Reverse();
Write(string.Concat(ans));
}
#region Main
protected static TextReader reader;
protected static TextWriter writer;
static void Main()
{
#if DEBUG
reader = new StreamReader("..\\..\\input.txt");
//reader = new StreamReader(Console.OpenStandardInput());
writer = Console.Out;
//writer = new StreamWriter("..\\..\\output.txt");
#else
reader = new StreamReader(Console.OpenStandardInput());
writer = new StreamWriter(Console.OpenStandardOutput(),Encoding.ASCII);
//reader = new StreamReader("input.txt");
//writer = new StreamWriter("output.txt");
#endif
try
{
new Solver().Solve();
//var thread = new Thread(new Solver().Solve, 1024 * 1024 * 128);
//thread.Start();
//thread.Join();
}
catch (Exception ex)
{
#if DEBUG
Console.WriteLine(ex);
#else
throw;
#endif
}
reader.Close();
writer.Close();
}
#endregion
#region Read / Write
private static Queue<string> currentLineTokens = new Queue<string>();
private static string[] ReadAndSplitLine() { return reader.ReadLine().Split(new[] { ' ', '\t', }, StringSplitOptions.RemoveEmptyEntries); }
public static string ReadToken() { while (currentLineTokens.Count == 0)currentLineTokens = new Queue<string>(ReadAndSplitLine()); return currentLineTokens.Dequeue(); }
public static int ReadInt() { return int.Parse(ReadToken()); }
public static long ReadLong() { return long.Parse(ReadToken()); }
public static double ReadDouble() { return double.Parse(ReadToken(), CultureInfo.InvariantCulture); }
public static int[] ReadIntArray() { return ReadAndSplitLine().Select(int.Parse).ToArray(); }
public static long[] ReadLongArray() { return ReadAndSplitLine().Select(long.Parse).ToArray(); }
public static double[] ReadDoubleArray() { return ReadAndSplitLine().Select(s => double.Parse(s, CultureInfo.InvariantCulture)).ToArray(); }
public static int[][] ReadIntMatrix(int numberOfRows) { int[][] matrix = new int[numberOfRows][]; for (int i = 0; i < numberOfRows; i++)matrix[i] = ReadIntArray(); return matrix; }
public static int[][] ReadAndTransposeIntMatrix(int numberOfRows)
{
int[][] matrix = ReadIntMatrix(numberOfRows); int[][] ret = new int[matrix[0].Length][];
for (int i = 0; i < ret.Length; i++) { ret[i] = new int[numberOfRows]; for (int j = 0; j < numberOfRows; j++)ret[i][j] = matrix[j][i]; } return ret;
}
public static string[] ReadLines(int quantity) { string[] lines = new string[quantity]; for (int i = 0; i < quantity; i++)lines[i] = reader.ReadLine().Trim(); return lines; }
public static void WriteArray<T>(IEnumerable<T> array) { writer.WriteLine(string.Join(" ", array)); }
public static void Write(params object[] array) { WriteArray(array); }
public static void WriteLines<T>(IEnumerable<T> array) { foreach (var a in array)writer.WriteLine(a); }
private class SDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
public new TValue this[TKey key]
{
get { return ContainsKey(key) ? base[key] : default(TValue); }
set { base[key] = value; }
}
}
private static T[] Init<T>(int size) where T : new() { var ret = new T[size]; for (int i = 0; i < size; i++)ret[i] = new T(); return ret; }
#endregion
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment