Advertisement
Guest User

Untitled

a guest
Jan 19th, 2017
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.36 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. class Solution
  6. {
  7. /*
  8. * January 19, 2016
  9. */
  10. public struct Group
  11. {
  12. public int Links;
  13. public Stack<int> Nodes;
  14.  
  15. /*
  16. * Small group will join the bigger group.
  17. */
  18. public static void MergeSmallGroupToLargeOne(
  19. Group[] groups,
  20. int smallGroupId,
  21. int bigGroupId,
  22. int[] nodeGroupId)
  23. {
  24. groups[bigGroupId].Links += groups[smallGroupId].Links + 1;
  25.  
  26. Stack<int> destination = groups[bigGroupId].Nodes;
  27. Stack<int> source = groups[smallGroupId].Nodes;
  28.  
  29. while (source.Count > 0)
  30. {
  31. int node = source.Pop();
  32. nodeGroupId[node] = bigGroupId;
  33. destination.Push(node);
  34. }
  35. }
  36.  
  37. /*
  38. * Go over the calculation formula
  39. *
  40. */
  41. public static ulong CalculateValue(Group[] sortedGroups)
  42. {
  43. ulong additionalLinks = 0;
  44. ulong totalValueOfFriendship = 0;
  45. ulong totalFriends = 0;
  46.  
  47. // Each group is maximized in order... additionalLinks added at end
  48. foreach (Group group in sortedGroups)
  49. {
  50. ulong links = (ulong)(group.Nodes.Count - 1);
  51.  
  52. ulong lookupValue = FriendshipValueCalculation.GetLookupTable()[links];
  53. totalValueOfFriendship += lookupValue + totalFriends * links;
  54.  
  55. additionalLinks += (ulong)group.Links - links;
  56.  
  57. totalFriends += links * (links + 1);
  58. }
  59.  
  60. totalValueOfFriendship += additionalLinks * totalFriends;
  61.  
  62. return totalValueOfFriendship;
  63. }
  64.  
  65. /*
  66. * filter out empty group, check Group class member
  67. * @groupCount - total groups, excluding merged groups
  68. * @groupIndex - total groups, including merged groups
  69. *
  70. * check Nodes in the stack, if the stack is empty, then the group is empty.
  71. */
  72. public static Group[] GetNonemptyGroups(int groupCount, int groupIndex, Group[] groups)
  73. {
  74. Group[] nonEmptyGroups = new Group[groupCount];
  75.  
  76. int index = 0;
  77. for (int i = 1; i <= groupIndex; i++)
  78. {
  79. if (groups[i].Nodes.Count > 0)
  80. {
  81. nonEmptyGroups[index++] = groups[i];
  82. }
  83. }
  84.  
  85. return nonEmptyGroups;
  86. }
  87. }
  88.  
  89. /*
  90. * Design talk:
  91. * 1 <= n <= 100,000, n is the total students
  92. * 1 <= m <= 2 * 100,000, m is the total friendship
  93. * @groups -
  94. * @groupIdMap -
  95. */
  96. public class GroupManagement
  97. {
  98. public Group[] groups;
  99. public int[] groupIdMap;
  100. public int groupIndex = 0;
  101. public int groupCount = 0;
  102.  
  103. public GroupManagement(int totalStudents)
  104. {
  105. groups = new Group[totalStudents / 2 + 1]; //
  106. groupIdMap = new int[totalStudents + 1]; // less than 2MB
  107. groupIndex = 0;
  108. groupCount = 0;
  109. }
  110.  
  111. /*
  112. 1) neither in a group: create new group with 2 nodes
  113. 2) only one in a group: add the other
  114. 3) both already in same group - increase Links
  115. 4) both already in different groups... join groups
  116. *
  117. */
  118. public void AddFriendshipToGroups(int id1, int id2)
  119. {
  120. int groupId1 = groupIdMap[id1];
  121. int groupId2 = groupIdMap[id2];
  122.  
  123. if (groupId1 == 0 || groupId2 == 0)
  124. {
  125. if (groupId1 == 0 && groupId2 == 0)
  126. {
  127. groupIndex++;
  128. groupCount++;
  129.  
  130. groups[groupIndex].Links = 1;
  131. groups[groupIndex].Nodes = new Stack<int>();
  132. groups[groupIndex].Nodes.Push(id1);
  133. groups[groupIndex].Nodes.Push(id2);
  134.  
  135. groupIdMap[id1] = groupIndex;
  136. groupIdMap[id2] = groupIndex;
  137. }
  138. else if (groupId1 == 0)
  139. {
  140. // add student1 into student2's group
  141. groups[groupId2].Nodes.Push(id1);
  142. groups[groupId2].Links++;
  143.  
  144. groupIdMap[id1] = groupId2;
  145. }
  146. else
  147. {
  148. // add student2 into studnet1's group
  149. groups[groupId1].Nodes.Push(id2);
  150. groups[groupId1].Links++;
  151. groupIdMap[id2] = groupId1;
  152. }
  153. }
  154. else
  155. {
  156. if (groupId1 == groupId2)
  157. {
  158. groups[groupId1].Links++;
  159. }
  160. else // merge two groups
  161. {
  162. groupCount--;
  163. int groupSize1 = groups[groupId1].Nodes.Count;
  164. int groupSize2 = groups[groupId2].Nodes.Count;
  165.  
  166. if (groupSize1 < groupSize2)
  167. {
  168. // small, big, groupId, nodeGroupId
  169. Group.MergeSmallGroupToLargeOne(groups, groupId1, groupId2, groupIdMap);
  170. }
  171. else
  172. {
  173. Group.MergeSmallGroupToLargeOne(groups, groupId2, groupId1, groupIdMap);
  174. }
  175. }
  176. }
  177. }
  178. }
  179.  
  180. /*
  181. * descending
  182. */
  183. public class GroupComparer : Comparer<Group>
  184. {
  185. public override int Compare(Group x, Group y)
  186. {
  187. return (y.Nodes.Count - x.Nodes.Count);
  188. }
  189. }
  190.  
  191. /*
  192. * add some calculation description here.
  193. */
  194. public class FriendshipValueCalculation
  195. {
  196. public static long FRIENDSHIPS_MAXIMUM = 200000;
  197.  
  198. public static ulong[] GetLookupTable()
  199. {
  200. ulong[] friendshipsLookupTable = new ulong[FRIENDSHIPS_MAXIMUM]; // 1.6 MB
  201.  
  202. ulong valueOfFriendship = 0;
  203.  
  204. for (int i = 1; i < FRIENDSHIPS_MAXIMUM; i++)
  205. {
  206. valueOfFriendship += (ulong)i * (ulong)(i + 1);
  207. friendshipsLookupTable[i] = valueOfFriendship;
  208. }
  209.  
  210. return friendshipsLookupTable;
  211. }
  212. }
  213.  
  214. static void Main(String[] args)
  215. {
  216. ProcessInput();
  217. //RunSampleTestcase();
  218. //RunSampleTestcase2();
  219. }
  220.  
  221. public static void ProcessInput()
  222. {
  223. GroupComparer headComparer = new GroupComparer();
  224.  
  225. int queries = Convert.ToInt32(Console.ReadLine());
  226. for (int query = 0; query < queries; query++)
  227. {
  228. string[] tokens_n = Console.ReadLine().Split(' ');
  229. int studentsCount = Convert.ToInt32(tokens_n[0]);
  230. int friendshipsCount = Convert.ToInt32(tokens_n[1]);
  231.  
  232. GroupManagement groupManager = new GroupManagement(studentsCount);
  233.  
  234. for (int i = 0; i < friendshipsCount; i++)
  235. {
  236. string[] relationship = Console.ReadLine().Split(' ');
  237.  
  238. int id1 = Convert.ToInt32(relationship[0]);
  239. int id2 = Convert.ToInt32(relationship[1]);
  240.  
  241. groupManager.AddFriendshipToGroups(id1, id2);
  242. }
  243.  
  244. // Get all groups large to small
  245. Group[] sortedGroups =
  246. Group.GetNonemptyGroups(
  247. groupManager.groupCount,
  248. groupManager.groupIndex,
  249. groupManager.groups);
  250.  
  251. Array.Sort(sortedGroups, headComparer);
  252.  
  253. Console.WriteLine(Group.CalculateValue(sortedGroups));
  254. }
  255. }
  256.  
  257. /*
  258. *
  259. * Need to work on the sample test case
  260. * 1. student 1 and 2 become friends
  261. * 1-2 3 4 5, we then sum the number of friends that each student has
  262. * to get 1 + 1 + 0 + 0 + 0 = 2.
  263. * 2. Student 2 and 3 become friends:
  264. * 1-2-3 4 5, we then sum the number of friends that each student has to get
  265. * 2 + 2 + 2 + 0 + 0 = 6.
  266. * 3. Student 4 and 5 become friends:
  267. * 1-2-3 4-5, we then sum the number of friends that each student has to get
  268. * 2 + 2 + 2 + 1 + 1 = 8.
  269. * 4. Student 1 and 3 become friends: (we hold to add 1 and 3 until 4 and 5
  270. * are added to maximize the value.)
  271. * 1-2-3 4-5, we then sum the number of friends that each student has to get
  272. * 2 + 2 + 2 + 1 + 1 = 8.
  273. * Total is 2 + 6 + 8 + 8 = 24.
  274. */
  275. public static void RunSampleTestcase()
  276. {
  277. string[][] datas = new string[1][];
  278. datas[0] = new string[2];
  279. datas[0][0] = "5";
  280. datas[0][1] = "4";
  281.  
  282. string[][] allFriendships = new string[1][];
  283. allFriendships[0] = new string[4];
  284.  
  285. allFriendships[0][0] = "1 2";
  286. allFriendships[0][1] = "2 3";
  287. allFriendships[0][2] = "1 3";
  288. allFriendships[0][3] = "4 5";
  289.  
  290. Console.WriteLine(HelpTestCase(datas, allFriendships));
  291. }
  292.  
  293. public static void RunSampleTestcase2()
  294. {
  295. string[][] datas = new string[1][];
  296. datas[0] = new string[2];
  297. datas[0][0] = "5";
  298. datas[0][1] = "4";
  299.  
  300. string[][] allFriendships = new string[1][];
  301. allFriendships[0] = new string[4];
  302.  
  303. allFriendships[0][0] = "1 2";
  304. allFriendships[0][1] = "3 2";
  305. allFriendships[0][2] = "4 2";
  306. allFriendships[0][3] = "4 3";
  307.  
  308. Console.WriteLine(HelpTestCase(datas, allFriendships));
  309. }
  310.  
  311. private static ulong HelpTestCase(string[][] datas, string[][] allFriendships)
  312. {
  313. GroupComparer headComparer = new GroupComparer();
  314.  
  315. int studentsCount = Convert.ToInt32(datas[0][0]);
  316. int friendshipsCount = Convert.ToInt32(datas[0][1]);
  317.  
  318. GroupManagement groupManager = new GroupManagement(studentsCount);
  319.  
  320. for (int i = 0; i < friendshipsCount; i++)
  321. {
  322. string[] relationship = allFriendships[0][i].Split(' ');
  323.  
  324. int id1 = Convert.ToInt32(relationship[0]);
  325. int id2 = Convert.ToInt32(relationship[1]);
  326.  
  327. groupManager.AddFriendshipToGroups(id1, id2);
  328. }
  329.  
  330. // Get all groups large to small
  331. Group[] sortedGroups =
  332. Group.GetNonemptyGroups(
  333. groupManager.groupCount,
  334. groupManager.groupIndex,
  335. groupManager.groups);
  336.  
  337. Array.Sort(sortedGroups, headComparer);
  338.  
  339. return Group.CalculateValue(sortedGroups);
  340. }
  341. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement