Syntax Colorizer

permlink
using System;
using System.Collections.Generic;
using System.Text;

public class SoftwareCompanies
{
 private class NetworkFlow
 {
  public const int Infinity = int.MaxValue;
  private readonly int[,] cap;
  private readonly int[,] flow;
  private readonly int n;

  public NetworkFlow(int n)
  {
   this.n = n;
   cap = new int[n,n];
   flow = new int[n,n];
  }

  public int MaxFlow(int source, int sink)
  {
   int[] prev = new int[n];
   int res = 0;
   while (true)
   {
    bool found = Bfs(prev, source, sink);
    if (!found)
     break;
    int min = Infinity;
    for (int cur = sink; cur != source; cur = prev[cur])
     min = Math.Min(min, Residual(prev[cur], cur));
    res += min;
    for (int cur = sink; cur != source; cur = prev[cur])
    {
     flow[prev[cur], cur] += min;
     flow[cur, prev[cur]] -= min;
    }
   }
   return res;
  }

  public void AddEdge(int from, int to, int capacity)
  {
   cap[from, to] = capacity;
  }

  private bool Bfs(int[] prev, int source, int sink)
  {
   bool[] mark = new bool[prev.Length];
   for (int i = 0; i < prev.Length; i++)
   {
    prev[i] = -1;
    mark[i] = false;
   }
   Queue<int> q = new Queue<int>();
   q.Enqueue(source);
   while (q.Count > 0)
   {
    int cur = q.Dequeue();
    mark[cur] = true;
    for (int i = 0; i < n; i++)
    {
     if (i == cur || mark[i] || !CanGo(cur, i))
      continue;
     prev[i] = cur;
     mark[i] = true;
     q.Enqueue(i);
    }
   }
   return mark[sink];
  }

  private bool CanGo(int a, int b)
  {
   return cap[a, b] == Infinity || Residual(a, b) > 0;
  }

  private int Residual(int a, int b)
  {
   return cap[a, b] == Infinity ? Infinity : cap[a, b] - flow[a, b];
  }
 }

 public string[] produceData(string[] names, string[] process, int[] companyCost, int[] amount, string company1, string company2)
 {
  List<string> res = null;
  int maxFlow = 0;
  int cost = 0;
  string[][] processSplitted = new string[process.Length][];
  for (int i = 0; i < processSplitted.Length; i++)
   processSplitted[i] = process[i].Split();

  for (int mask = 0; mask < (1 << names.Length); mask++)
  {
   Dictionary<string, int> ids = new Dictionary<string, int>();
   int nextId = 0;
   int ncost = 0;
   for (int i = 0; i < names.Length; i++)
   {
    if (HasBit(mask, i))
    {
     ids[names[i]] = nextId++;
     ncost += companyCost[i];
    }
   }
   if (!ids.ContainsKey(company1) || !ids.ContainsKey(company2))
    continue;

   NetworkFlow nf = new NetworkFlow(ids.Count*2);
   for (int i = 0; i < process.Length; i++)
   {
    if (HasBit(mask, i))
    {
     int myId = ids[names[i]];
     foreach (string next in processSplitted[i])
     {
      if (ids.ContainsKey(next))
       nf.AddEdge(2*myId + 1, 2*ids[next], NetworkFlow.Infinity);
     }
     nf.AddEdge(2*myId, 2*myId + 1, amount[i]);
    }
   }

   int nflow = nf.MaxFlow(2*ids[company1], 2*ids[company2] + 1);
   CheckBetterFlow(ref res, mask, nflow, ref maxFlow, ncost, ref cost, names);
  }
  return res == null ? new string[0] : res.ToArray();
 }

 private void CheckBetterFlow(ref List<string> res, int mask, int nflow, ref int maxFlow, int ncost, ref int cost, string[] names)
 {
  if (nflow == 0)
   return;
  List<string> sln = new List<string>();
  for (int i = 0; i < names.Length; i++)
  {
   if (HasBit(mask, i))
    sln.Add(names[i]);
  }
  sln.Sort();
  if (nflow > maxFlow || nflow == maxFlow && ncost < cost || nflow == maxFlow && ncost == cost && Less(sln, res))
  {
   maxFlow = nflow;
   cost = ncost;
   res = sln;
  }
 }

 private bool Less(List<string> cand, List<string> res)
 {
  if (res == null)
   return true;
  for (int i = 0; i < Math.Min(cand.Count, res.Count); i++)
  {
   if (cand[i] != res[i])
    return cand[i].CompareTo(res[i]) < 0;
  }
  return cand.Count < res.Count;
 }

 private bool HasBit(int mask, int bit)
 {
  return (mask & (1 << bit)) != 0;
 }
}

For you blog

For web page

About | Send us feedback